diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a39f67..9b9061d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,8 +47,8 @@ Non-code commits (documentation, planning, README-only updates) are excluded. ## v3.9.0 - **Description:** Introduced clearer sharing flows for Live Share and Share Snapshot, with fixes for shared Markdown rendering and desktop startup. - - **Live Share:** Live Share creates a temporary in-memory room for real-time collaboration. The document is synced only while the room is active, and the room is not saved as a permanent document store. Participants join through the invite link and can either edit or view only, depending on the access mode selected by the host. - - **Share Snapshot:** Share Snapshot creates a shareable read-only or editable snapshot link. Small documents stay encoded directly inside the URL hash. Larger documents are saved behind a generated `#share=` ID and kept temporarily for 90 days, so the recipient can open the shared document without it being stored on their own device. + - **Live Share:** Live Share introduced temporary real-time collaboration through a Cloudflare room. Markdown content is synchronized between active clients rather than stored as a permanent server-side Document. Participants join through the invite link with Can edit or View only access, depending on the mode selected by the host. + - **Share Snapshot:** Share Snapshot creates a point-in-time link with View only or Can edit access. Small documents stay encoded directly inside the `#share=...` URL hash. Larger documents are stored for 90 days and opened through a generated `#id=...` link; recipient tabs remain temporary rather than being added to the saved Workspace. - **Shared Rendering:** Fixed shared Snapshot and Live Share participant views so LaTeX, Mermaid, TopoJSON, and other advanced Markdown renderers complete after the shared document loads. - **Sharing UX:** The Live Share modal now shows only the display name, access mode, and start button before a room starts. Participant and invite-link sections appear only after the live room is active. - **Desktop Startup:** Fixed the Neutralino desktop build preparation so bundled resources load the generated application script instead of stalling on startup skeletons. @@ -72,9 +72,9 @@ Non-code commits (documentation, planning, README-only updates) are excluded. ## v3.8.0 -- **Description:** Delivered substantial new feature expansions and reliability enhancements, including diagram insertion workflow with live card previews, client-side rendering engines (PlantUML, D2, Graphviz), interactive ABC notation playback sync, export quality boosts, desktop data persistence, and layout fixes for squished or overlapping diagrams. +- **Description:** Delivered substantial new feature expansions and reliability enhancements, including diagram insertion with live card previews, PlantUML/D2/Graphviz renderer integrations, interactive ABC notation playback sync, export quality improvements, desktop data persistence, and layout fixes for squished or overlapping diagrams. - **Insert Diagram Modal:** Added an interactive "Insert Diagram" modal featuring high-fidelity static SVGs, actual live rendering of diagrams in split views, and a categorized search filter. - - **New Diagram Engines Support:** Integrated client-side rendering support for PlantUML, D2, Graphviz (DOT), Vega-Lite, Wavedrom, and Markmap diagrams via dynamic libraries and Kroki API fallbacks for browser/offline environments. + - **New Diagram Engines Support:** Added PlantUML, D2, Graphviz (DOT), Vega-Lite, WaveDrom, and Markmap integrations. The standard web paths use remote PlantUML/Kroki services for remote engines and client-side Markmap libraries. - **Interactive Diagram Toolbars:** Built interactive toolbar options (zoom, pan, copy SVG/PNG, reset, fit-to-view) for newly introduced engines. - **ABC Notation Enhancements:** Implemented synchronized playback cursor and note highlighting for synthesized audio playbacks and custom export actions. - **High-Definition Image Export:** Increased PNG export resolution to 3x for crisp, high-definition diagrams, and added solid backgrounds to transparent SVG renders to preserve visibility. diff --git a/README.md b/README.md index 051f188c..d6404f82 100644 --- a/README.md +++ b/README.md @@ -1,317 +1,194 @@
- Markdown Viewer Logo + Markdown Viewer logo -

Markdown Viewer - Online Markdown Editor with Live Preview

+

Markdown Viewer

- **A browser-based Markdown editor, viewer, previewer, and reader.** + **A local-first Markdown editor and viewer with live preview.** - *Open, read, edit, and preview `.md` files with split-screen live Markdown preview, sync scrolling, GitHub-Flavored Markdown, diagrams, maps, 3D STL previews, ABC notation playback, PDF/HTML/PNG export, and multi-tab support across web, desktop, and Docker.* + Open, write, organize, review, render, export, and optionally share Markdown in a browser, as a Progressive Web App (PWA), in Docker, or in the Neutralino desktop application. - [![License](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/LICENSE) - [![Latest Release](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) - [![Last Commit](https://img.shields.io/github/last-commit/ThisIs-Developer/Markdown-Viewer?style=flat-square)](https://github.com/ThisIs-Developer/Markdown-Viewer/commits/main) - [![Stars](https://img.shields.io/github/stars/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=dfb317)](https://github.com/ThisIs-Developer/Markdown-Viewer/stargazers) + [![License](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](LICENSE) + [![Latest release](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)

- CodeWiki + Explore Markdown Viewer on CodeWiki - DeepWiki + Explore Markdown Viewer on DeepWiki

- 🌐 **English** • [简体中文](locales/README_zh.md) • [日本語](locales/README_ja.md) • [한국어](locales/README_ko.md) • More Languages + **English** · [日本語](locales/README_ja.md) · [한국어](locales/README_ko.md) · [简体中文](locales/README_zh.md) · [繁體中文](locales/README_tw.md) - [Live Production Demo](https://markdownviewer.pages.dev/) • [Wiki](wiki/Home.md#start-here) • [Issue Tracker](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) • [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + [Open the web app](https://markdownviewer.pages.dev/) · [Start with the documentation](wiki/Home.md) · [Report an issue](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) · [View releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)
-## Table of Contents -
- 📂 Table of Contents (Click to expand) -
- - - [About the Project](#about-the-project) - - [Try It Quickly](#try-it-quickly) - - [Key Features](#key-features) - - [Media Support and Storage](#media-support-and-storage) - - [Diagrams and Visual Content](#diagrams-and-visual-content) - - [Sharing, Collaboration, and Export](#sharing-collaboration-and-export) - - [System Architecture](#system-architecture) - - [Core File Walkthrough](#core-file-walkthrough) - - [Getting Started & Installation](#getting-started--installation) - - [Usage Guide & Keyboard Shortcuts](#usage-guide--keyboard-shortcuts) - - [Project Directory Structure](#project-directory-structure) - - [Built With (Technology Stack)](#built-with-technology-stack) - - [Privacy](#privacy) - - [Security and Privacy Controls](#security-and-privacy-controls) - - [Contributing & Code Quality](#contributing--code-quality) - - [Showcase & Community Projects](#showcase--community-projects) - - [Contributors](#contributors) - - [📈 Development Journey](#-development-journey) - - [License](#license) - - [Contact & Support](#contact--support) -
+Table of contents (click to expand) + +- [What Markdown Viewer Does](#what-markdown-viewer-does) +- [Highlights](#highlights) +- [Quick Start](#quick-start) +- [Local and Network Behavior](#local-and-network-behavior) +- [Visual Renderer Summary](#visual-renderer-summary) +- [Documentation](#documentation) +- [Important Limits](#important-limits) +- [Showcase Projects](#showcase-projects) +- [Development Journey](#development-journey) +- [Contributors](#contributors) +- [Contributing and Support](#contributing-and-support) +- [License](#license) ---- + -## About the Project +## What Markdown Viewer Does -**Markdown Viewer** is an open source, browser-based Markdown editor and viewer for `.md` and `.markdown` files. It combines plain Markdown editing with a live GitHub-style preview, document tabs, diagram-as-code tools, math, exports, sharing, and desktop/web deployment options. +Markdown Viewer is an open source, local-first workspace for developers, writers, students, researchers, and anyone working with `.md` or `.markdown` files. Go beyond plain text. Organize multiple documents, review with comments and suggestions without changing the Markdown, and render diagrams, maps, charts, math, 3D models, and music—all in one focused workspace. -Most editing, previewing, autosave, local file import, settings, and export work happens on your device. Network features are explicit and documented. No login is required. +Turn a document into a Share Snapshot link for quick handoffs, or start access-controlled Live Share for real-time co-editing, live cursors, comments, and suggestions. Everyday editing stays on your device. No account is required, and the application includes no ads, analytics, telemetry, or subscriptions.

- Markdown Viewer - Live split-screen Markdown editor and previewer with GFM rendering, tabbed multi-document workspace, and dark theme support + Application UI

-## Try It Quickly - -1. Open the [live online Markdown editor](https://markdownviewer.pages.dev/). -2. Drag in a `.md` or `.markdown` file, or start writing in the editor. -3. Use the live preview, **Insert Diagram & More**, export menu, Share Snapshot, or Live Share depending on your workflow. - -For detailed notes, see the wiki sections for [features](wiki/Features.md#product-summary), [privacy](wiki/Home.md#privacy-at-a-glance), [sharing](wiki/Features.md#share-markdown-with-snapshot-links), [exports](wiki/Features.md#export-markdown-to-pdf-html-png-and-md), and [desktop](wiki/Features.md#desktop-app). - -## Key Features - -Markdown Viewer handles the usual Markdown basics, but its real value is helping users build richer technical documents without leaving the editor. - -1. **GitHub-Flavored Markdown (GFM)**: write normal Markdown with tables, task lists, strikethrough, autolinks, code blocks, alerts, footnotes, and live preview. Most Markdown editors cover the basics; the features below show what Markdown Viewer adds for richer technical documents. -2. **Advanced Diagram Support & More**: insert diagrams, charts, maps, 3D models, and music notation from ready-to-use templates and previews. - -3. **Document Explorer & Two-Document Split**: organize up to 50 stored files in nested folders, use bulk file actions, and open two documents side by side with full Markdown, math, diagram, map, STL, and ABC rendering. -4. **Comments & Suggestions**: add, manage, and resolve feedback on rendered document blocks without changing the Markdown source. -5. **Live Share Temporary Rooms**: collaborate in real time for quick editing sessions, reviews, or pair-writing, with server-checked host, editable, and view-only capabilities. -6. **Share Snapshot Links**: create view-only or editable point-in-time links when you need to send a document state quickly. Large stored snapshots expire after 90 days. -7. **LaTeX Math Notation**: render inline and display formulas with MathJax, useful for math-heavy notes, papers, and technical explanations. -8. **Markdown to PDF, HTML & PNG Export**: export Markdown, HTML, PNG, Browser Print / Save as PDF, or Legacy Raster PDF for documents that need sharing, printing, or archiving. -9. **Privacy and Security Controls**: enable Private mode from Workspace settings to keep document and review data session-only, and rely on sanitized previews, hardened export HTML, and restricted desktop native APIs. - -For the full feature list, details, limitations, and privacy notes, see the [features reference](wiki/Features.md#product-summary). - -## Media Support and Storage +## Highlights -- Paste, upload, or drop AVIF, BMP, GIF (including animated GIFs), JPEG, PNG, and WebP images, plus MP4, WebM, or Ogg videos, at the editor cursor. -- After first-use consent, media is uploaded to temporary Cloudflare storage and inserted as a short, content-addressed HTTPS link. -- Managed media links are public to anyone who has them and expire 90 days after the latest upload of the same content. -- Share Snapshot and Live Share include the media link in the Markdown; they do not create another media copy. Recipients can view the media until its link expires. - - -## Diagrams and Visual Content - -Use **Insert Diagram & More** for ready-to-use templates and previews: - -- **Mermaid, PlantUML, Graphviz / DOT, and D2** for flowcharts, sequence diagrams, class diagrams, architecture sketches, dependency graphs, and diagram-as-code workflows. -- **Vega-Lite and Markmap** for Markdown charts, data visualization, and mind maps. -- **WaveDrom** for timing diagrams and signal documentation. -- **GeoJSON and TopoJSON maps** for location-aware Markdown documents. -- **STL 3D model previews** for inspecting 3D model snippets alongside notes. -- **ABC notation** for sheet music rendering and browser playback. +- **Workspace and documents:** organize up to 50 documents in nested folders; use Recent, Favorites, search, tabs, bulk actions, and an encrypted Secret Workspace. +- **Editing and review:** switch among Editor, Split view, and Preview; use formatting tools, custom undo/redo, Find and Replace, LTR/RTL direction, comments, and suggestions. +- **Markdown rendering:** use CommonMark-style Markdown, GitHub-Flavored Markdown (GFM), tables, task lists, alerts, footnotes, definition lists, syntax highlighting, sanitized HTML, and MathJax. +- **Visual content:** render Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL, and ABC notation.

- Diagram Support & More - ABC Music Notation & Audio Synthesis - STL 3D Model Renderer + Insert diagram module + Diagrams + 3D STL + 3D STL Full screen

-## Sharing, Collaboration, and Export +- **Import and export:** open local files or public GitHub content; export Markdown, standalone HTML, PNG, Browser Print/Save as PDF, or a legacy raster PDF. -- **Comments & Suggestions** adds a review layer to rendered YAML, headings, paragraphs, code blocks, and diagrams without changing Markdown. Feedback can be added, edited, resolved, reopened, deleted, or copied; it stays with normal tabs and synchronizes only during an active Live Share room. -- **Share Snapshot** creates quick links for point-in-time Markdown sharing. Small documents can stay in the URL hash; larger snapshots use temporary Cloudflare KV storage for up to 90 days when that backend is configured. Snapshot links are bearer links: anyone who has the link can open it. -

- Share Snapshot -

+- **Optional sharing:** create a Share Snapshot with View only or Can edit access, or start a temporary Live Share room with host, Can edit, and View only capabilities. -- **Live Share rooms** provide temporary collaborative editing through Cloudflare Durable Objects, with server-checked host, editable, and view-only capabilities. They are useful for reviews and pair-writing, but they are not end-to-end encrypted.

- Live Share rooms + Live share

-- **Exports:** download raw Markdown, standalone HTML, or a PNG of the rendered preview. PDF offers Browser Print / Save as PDF for selectable text and Legacy Raster PDF, which captures the rendered preview as page-sized images to preserve complex layouts. - ---- - -## System Architecture - -Markdown Viewer is a client-side single-page app. `script.js` controls the UI, `preview-worker.js` compiles Markdown off-thread, and `sw.js` handles offline-capable caching. - -### Core File Walkthrough - -1. **`index.html`**: App layout and script/style entry points. -2. **`script.js`**: Tabs, editor state, preview updates, imports, exports, sharing, and UI behavior. -3. **`styles.css`**: Layout, themes, preview styling, and print styles. -4. **`preview-worker.js`**: Off-thread Markdown parsing and syntax highlighting. -5. **`sw.js`**: Offline-capable asset caching. +- **Multiple delivery options:** use the hosted web app, install the PWA, self-host static files, run Docker, deploy on Cloudflare, or build the Neutralino desktop application. ---- +For verified behavior, limits, and implementation notes, read the [feature reference](wiki/Features.md). -## Getting Started & Installation +## Quick Start -### 💻 Option 1: Quick Local Run (No Installation) -Run through a local HTTP server instead of opening `index.html` with `file://`: -1. Clone or download the repository to your local machine. -2. Open a terminal in the repository folder. -3. Run `python -m http.server 8080` or `npx serve . -p 8080`. -4. Open **[http://localhost:8080](http://localhost:8080)** in your browser. +Use the hosted application at [markdownviewer.pages.dev](https://markdownviewer.pages.dev/), or run the repository through a local HTTP server: ---- - -### 🐳 Option 2: Docker Container Deployment -Run the app in a container: - -**Pre-built Docker Image (GHCR):** -```bash -docker run -d \ - --name markdown-viewer \ - -p 8080:80 \ - --restart unless-stopped \ - ghcr.io/thisis-developer/markdown-viewer:latest -``` -Open **[http://localhost:8080](http://localhost:8080)** in your browser. - -**Local Docker Compose Build:** ```bash git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git cd Markdown-Viewer -docker compose up -d +python -m http.server 8080 ``` -Open **[http://localhost:8080](http://localhost:8080)** in your browser. - ---- - -### 🖥️ Option 3: Building the Desktop Application -Build the Neutralinojs desktop app from source: -1. Clone the repository and navigate into the `desktop-app/` directory: - ```bash - cd desktop-app - ``` -2. Install dependencies and build: - ```powershell - npm install - npm run build - ``` - -`npm run build` downloads the required Neutralino binaries, prepares local resources, and creates seven self-contained platform executables. - -Prebuilt binaries are available from [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases). - ---- - -## Usage Guide & Keyboard Shortcuts -Read the [usage guide](wiki/Usage-Guide.md#workspace-layout-for-editing-and-previewing-markdown) for workflows, editor controls, exports, sharing, and keyboard shortcuts. +Open `http://localhost:8080`. Do not rely on `file://`; browser security rules can block Web Workers and Service Workers. ---- +Other options: -## Project Directory Structure +| Target | Start here | +| :--- | :--- | +| PWA or static web hosting | [Installation](wiki/Installation.md) | +| Docker | [Docker Deployment](wiki/Docker-Deployment.md) | +| Cloudflare Pages, KV, and Durable Objects | [Configuration](wiki/Configuration.md) | +| Neutralino desktop application | [Desktop Application](wiki/Desktop-App.md) | -``` -Markdown-Viewer/ -+-- index.html # Main web app shell -+-- script.js # App logic and UI controller -+-- styles.css # App and preview styles -+-- preview-worker.js # Markdown preview worker -+-- sw.js # Service worker cache behavior -+-- assets/ # App images and icons -| +-- i18n/ # Interface catalogs and locale generator -+-- functions/ # Cloudflare Pages Functions -+-- workers/ # Live Share Worker source -+-- desktop-app/ # Neutralinojs desktop build -+-- locales/ # Localized README summaries -+-- wiki/ # Project documentation -+-- Dockerfile # Docker image setup -+-- docker-compose.yml # Local container run config -+-- wrangler.toml # Cloudflare deployment config -+-- README.md # Main project overview -+-- CHANGELOG.md # Release history -+-- LICENSE # Apache License 2.0 -``` - ---- - -## Built With (Technology Stack) - -

- HTML5 - CSS3 - JavaScript - Bootstrap - NeutralinoJS -

+## Local and Network Behavior -Core stack: HTML, CSS, JavaScript, Bootstrap, Bootstrap Icons, Neutralinojs, Marked.js, Highlight.js, DOMPurify, MathJax, Mermaid, Leaflet, Three.js, ABCJS, Markmap, Yjs, jsPDF, html2canvas, and Cloudflare Pages/Workers. +Markdown Viewer is local-first, not network-free. The following table shows the main boundary: -For dependency loading behavior, CDN use, and local desktop library copies, see the [client library notes](wiki/Configuration.md#client-libraries). +| Workflow | Default data path | +| :--- | :--- | +| Editing, local imports, Preview, Workspace autosave, and most exports | On the device | +| Web libraries and uncached renderer dependencies | CDN requests in the web/PWA build | +| Public GitHub import and emoji lookup | GitHub APIs and raw-content hosts | +| PlantUML, D2, Graphviz, Vega-Lite, WaveDrom, and some diagram previews | Diagram source can be sent to PlantUML, Kroki, or mermaid.ink | +| Consented image, GIF, and video insertion | Public, content-addressed Cloudflare media storage for 90 days | +| Large Share Snapshot | Cloudflare KV for 90 days | +| Live Share | WebSocket relay through a Cloudflare Durable Object; document content is not persisted server-side | +| External images, media, links, and map tiles | The referenced external host | -Some advanced diagram engines use remote renderers such as PlantUML, Kroki, or mermaid.ink when needed. See the [diagram renderer notes](wiki/Features.md#insert-diagrams-charts-maps-models-and-music) for renderer behavior and privacy details. +Share Snapshot and Live Share URLs are bearer links. Anyone who obtains a valid link and capability can use the access it grants. Live Share is not end-to-end encrypted. See [Privacy and Security](wiki/Privacy-and-Security.md) before using network features with sensitive content. ---- +## Visual Renderer Summary -## Privacy +| Fence | Rendering path | +| :--- | :--- | +| `mermaid` | Client-side; insertion previews can use mermaid.ink or Kroki | +| `plantuml` | PlantUML server; Kroki fallback | +| `d2`, `graphviz`, `dot`, `vega-lite`, `vegalite`, `wavedrom` | Kroki | +| `markmap` | Client-side Markmap and D3 | +| `geojson`, `topojson` | Client-side Leaflet; map tiles can use the network | +| `stl` | Client-side Three.js/WebGL | +| `abc` | Client-side ABCJS; playback needs browser audio support | +| `math` and LaTeX delimiters | Client-side MathJax | -Markdown Viewer is not a cloud workspace. Normal typing, preview rendering, local file import, tab autosave, theme settings, and most exports happen on your device. No login is required, and the app does not implement analytics, telemetry, ads, or tracking cookies. +Remote renderer services receive the source of the diagram they render. Do not send sensitive diagram source unless you trust the configured service. See the [Markdown Reference](wiki/Markdown-Reference.md) for syntax and the [feature reference](wiki/Features.md#insert-diagrams-charts-maps-models-and-music) for limitations. -Network use is user-triggered for features such as consented managed-media upload, GitHub import, remote diagram renderers, Share Snapshot, Live Share, CDN libraries, and external document assets. Private mode in Workspace settings keeps document content, workspace state, and review feedback session-only while editing and review tools remain available. For the full reference, read the [data handling summary](wiki/Features.md#data-handling-summary). +## Documentation -## Security and Privacy Controls +| Need | Page | +| :--- | :--- | +| Choose a starting point | [Documentation Home](wiki/Home.md) | +| Review all product capabilities and limits | [Features](wiki/Features.md) | +| Learn day-to-day workflows and shortcuts | [Usage Guide](wiki/Usage-Guide.md) | +| Write supported Markdown and rich fences | [Markdown Reference](wiki/Markdown-Reference.md) | +| Understand Share Snapshot | [Share Snapshot](wiki/Share-Snapshot.md) | +| Understand Live Share | [Live Share](wiki/Live-Share-Cloudflare.md) | +| Review data handling and security boundaries | [Privacy and Security](wiki/Privacy-and-Security.md) | +| Install or deploy the product | [Installation](wiki/Installation.md) | +| Configure storage, renderers, and Cloudflare | [Configuration](wiki/Configuration.md) | +| Resolve common problems | [Troubleshooting](wiki/Troubleshooting.md) and [FAQ](wiki/FAQ.md) | +| Contribute code, documentation, or translations | [Contributing](wiki/Contributing.md) | +| Maintain translations and approved multilingual terms | [Localization and Terminology](wiki/Localization.md) | -- Preview HTML is sanitized before insertion, and exported HTML includes a restrictive CSP plus SRI metadata for its external assets. -- Secret Workspace derives a local encryption key from the user's password with PBKDF2-SHA-256 and encrypts its files and folder names with AES-GCM. The key is kept only for the unlocked browser session, and forgotten passwords cannot be recovered. -- Cloudflare Pages deployments use `_headers` for CSP, clickjacking protection, referrer and permissions policies, and no-sniff protection; sensitive paths are redirected to 404 responses. -- Managed media and stored Share Snapshot API uploads are limited to the production app, previews, `null`, and local development origins. Managed images, GIFs, and videos are public through unguessable immutable links for 90 days; stored snapshot responses are `no-store`, and snapshot creators receive a deletion token from the API. -- STL rendering rejects oversized sources, non-finite geometry, and excessive vertex counts before WebGL rendering. -- The Neutralino desktop build removes the default `os.execCommand` exposure and keeps native APIs on an explicit allowlist. See the [security model](wiki/Features.md#security-model) and [configuration reference](wiki/Configuration.md#share-api). +## Important Limits ---- +- The Workspace limit is 50 documents, including locked Secret Workspace counts and temporary Share Snapshot or Live Share tabs. +- A local Markdown file larger than 10 MB is rejected. +- The public GitHub importer shows at most 30 Markdown files for a repository or folder result. +- Managed source media is limited to 25 MiB before processing; stored payload limits are 300 KiB for still images, 5 MiB for GIFs, and 10 MiB for videos. +- Stored Share Snapshot content is limited to 8,000,000 characters and expires after 90 days. +- Live Share allows up to 64 WebSocket participants and 8 MB per live message. +- STL source is limited to 2 MiB and rendered geometry to 300,000 vertices. +- Raster PDF and PNG exports remain subject to browser memory, canvas, and cross-origin resource limits. -## Contributing & Code Quality +See [Features: Known Technical Limits](wiki/Features.md#known-technical-limits) for context. -We welcome community contributions! Please check [contributing before changing code](wiki/Contributing.md#before-changing-code) before creating a pull request. +## Showcase Projects -### Core Workflow Summary: -1. **Fork** the repository and create a feature branch (`git checkout -b feature/your-feature`). -2. **Verify Code Style:** Maintain a clean 2-space indentation style across HTML, CSS, and JS files. Ensure raw HTML structures are semantic. Avoid direct DOM queries inside processing workers. -3. **Conventional Commits:** Write clear commit messages prefixed with `feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `perf:`, or `chore:`. -4. **Testing:** Test your revisions across Chrome, Firefox, Edge, and Safari viewports. +The following community project builds on Markdown Viewer and is maintained independently: ---- +- [**Markdown Desk**](https://github.com/jhrepo/markdown-desk): A native macOS wrapper built with Tauri that adds native file dialogs and handlers, menu-bar integration, automatic reloads, and in-app updates. -## Showcase & Community Projects +## Development Journey -* **[Markdown Desk](https://github.com/jhrepo/markdown-desk):** A native macOS wrapper built using Tauri that adds native file-system handlers, menu bar integration, and auto-reload capabilities. +Markdown Viewer started as a small personal project on a PC: a simple Markdown viewer built with curiosity, mistakes, fixes, and a lot of care. The original version is still online and remains at the heart of the project. ---- +Read the [Development Journey](wiki/Development-Journey.md) for the longer project history. ## Contributors -Thanks to everyone who has contributed to Markdown Viewer. +Markdown Viewer grows through contributions from its community. - Contributors + Markdown Viewer contributors ---- +## Contributing and Support -## 📈 Development Journey +Read [Contributing](wiki/Contributing.md) before opening a pull request. Use the [issue tracker](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) for reproducible bugs and focused feature requests. -Markdown Viewer started as a small personal project on a PC: a simple Markdown viewer built with curiosity, mistakes, fixes, and a lot of care. The original version is still online, and it remains the heart of the project. - -The current Markdown Viewer grew through community feedback, issues, PRs, screenshots, GIFs, suggestions, and real documentation workflows. The technical progress matters, but the journey is also emotional: people helped shape the app into what it is today. - ---- +Do not publish vulnerability details in a normal issue. Use the repository's private security-reporting channel when available, as described in [Contributing: Security Reports](wiki/Contributing.md#security-reports). ## License -This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for the complete terms and conditions. - ---- - -## Contact & Support - -Developed and maintained by **[ThisIs-Developer](https://github.com/ThisIs-Developer)**. -* **Bug Reports & Requests:** [Submit an Issue](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) -* **Documentation:** [Wiki start here](wiki/Home.md#start-here) +Markdown Viewer is licensed under the [Apache License 2.0](LICENSE). diff --git a/desktop-app/README.md b/desktop-app/README.md index a7f175cb..2bfb7bcd 100644 --- a/desktop-app/README.md +++ b/desktop-app/README.md @@ -1,12 +1,12 @@ -# Markdown Viewer Desktop App +# Markdown Viewer Desktop Application -This folder contains the Neutralinojs desktop wrapper for Markdown Viewer. It turns the browser-based Markdown editor, viewer, and reader into a lightweight desktop build for opening local `.md` files, using split live preview, exporting documents, and working with native file dialogs. It reuses the root web app and adds window lifecycle handling, desktop storage mirroring, and prepared local renderer assets. +This folder contains the Neutralinojs desktop wrapper for Markdown Viewer. It turns the browser-based Markdown editor and viewer into a lightweight desktop build for opening local `.md` files, using Split view and live Preview, exporting Documents, and working with native file dialogs. It reuses the root web app and adds window lifecycle handling, desktop storage mirroring, and prepared local renderer assets. -For the complete product behavior and privacy reference, see [../wiki/Features.md](../wiki/Features.md). +For complete product behavior, see [Features](../wiki/Features.md). For storage and network boundaries, see [Privacy and Security](../wiki/Privacy-and-Security.md). ## Architecture -The desktop app shares the same core product code as the browser version: +The desktop application shares the same core product code as the browser version: - `../index.html` - `../script.js` @@ -32,6 +32,7 @@ Desktop-only files: - A Markdown file passed as a launch argument is loaded into the editor. - The app asks before closing the window. - Prepared desktop resources load dynamic libraries from local `/libs/...` paths after setup. +- Private mode and **Reset workspace** clear persisted normal and Secret Workspace Document data. Export needed Documents before using either control. Network features still use the network when invoked: managed media upload, GitHub import, stored Share Snapshot, Live Share, remote diagram rendering, external images, and external links. @@ -78,9 +79,9 @@ Native APIs are intentionally allowlisted: app exit, open/save dialogs, message ## Local Renderer Security -Markdown content is treated as untrusted input. The desktop app does not allow Markdown preview rendering to run local shell commands by default. Native file open/save remains available through Neutralino dialogs and filesystem APIs. +Markdown content is treated as untrusted input. The desktop application does not allow Markdown Preview rendering to run local shell commands by default. Native file open/save remains available through Neutralino dialogs and filesystem APIs. -Remote-safe diagram rendering continues to work where supported. Local command renderers such as D2 or PlantUML should only be enabled in a custom build after the user has explicitly accepted that local renderer programs process document content on their machine, and only fixed commands with stdin input should be allowed. +Remote diagram rendering continues to work where supported. PlantUML and D2 use their remote paths in the standard build. Local command renderers should only be enabled in a custom build after the user has explicitly accepted that local renderer programs process Document content on the machine, and only fixed commands with standard input should be allowed. ## Docker Build diff --git a/locales/README_ja.md b/locales/README_ja.md index ab43f1a5..778b4b06 100644 --- a/locales/README_ja.md +++ b/locales/README_ja.md @@ -1,339 +1,189 @@
- Markdown Viewer Logo + Markdown Viewer のロゴ -

Markdown Viewer - ライブプレビュー付きオンライン Markdown エディター

+

Markdown Viewer

- **ブラウザーで使える Markdown エディター、ビューアー、プレビューアー、リーダーです。** + **ライブプレビューを備えた、ローカルファーストの Markdown エディター/ビューアー** - *`.md` ファイルを開き、読み、編集し、分割画面のライブ Markdown プレビュー、同期スクロール、GitHub-Flavored Markdown、図表、地図、3D STL プレビュー、ABC 記譜再生、PDF/HTML/PNG エクスポート、Web/デスクトップ/Docker のマルチタブ作業に対応します。* + ブラウザー、Progressive Web App(PWA)、Docker、Neutralino デスクトップアプリケーションで Markdown を開き、編集、整理、レビュー、描画、エクスポートできます。必要に応じて共有や共同編集も利用できます。 - [![License](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/LICENSE) - [![Latest Release](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) - [![Last Commit](https://img.shields.io/github/last-commit/ThisIs-Developer/Markdown-Viewer?style=flat-square)](https://github.com/ThisIs-Developer/Markdown-Viewer/commits/main) - [![Stars](https://img.shields.io/github/stars/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=dfb317)](https://github.com/ThisIs-Developer/Markdown-Viewer/stargazers) + [![ライセンス](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](../LICENSE) + [![最新リリース](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)

- CodeWiki + CodeWiki で Markdown Viewer を見る - DeepWiki + DeepWiki で Markdown Viewer を見る

- 🌐 [English](../README.md) • [简体中文](README_zh.md) • **日本語** • [한국어](README_ko.md) • その他の言語 + [English](../README.md) · **日本語** · [한국어](README_ko.md) · [简体中文](README_zh.md) · [繁體中文](README_tw.md) - [ライブデモ](https://markdownviewer.pages.dev/) • [Wiki](../wiki/Home.md#start-here) • [Issue トラッカー](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) • [リリース](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + [Web アプリを開く](https://markdownviewer.pages.dev/) · [ドキュメント(英語)](../wiki/Home.md) · [Issue を報告](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) · [リリース](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)
-## 目次 -
- 📂 目次(クリックして展開) -
- - - [プロジェクト概要](#プロジェクト概要) - - [すぐに試す](#すぐに試す) - - [主な機能](#主な機能) - - [Markdown 編集とライブプレビュー](#markdown-編集とライブプレビュー) - - [図表とビジュアルコンテンツ](#図表とビジュアルコンテンツ) - - [共有、共同編集、エクスポート](#共有共同編集エクスポート) - - [システム構成](#システム構成) - - [主要ファイル](#主要ファイル) - - [開始方法とインストール](#開始方法とインストール) - - [使い方とキーボードショートカット](#使い方とキーボードショートカット) - - [プロジェクトディレクトリ構成](#プロジェクトディレクトリ構成) - - [Built With(技術スタック)](#built-with技術スタック) - - [プライバシー](#プライバシー) - - [セキュリティとプライバシーの管理](#セキュリティとプライバシーの管理) - - [コントリビューションとコード品質](#コントリビューションとコード品質) - - [ショーケースとコミュニティプロジェクト](#ショーケースとコミュニティプロジェクト) - - [コントリビューター](#コントリビューター) - - [📈 開発の歩み](#-開発の歩み) - - [ライセンス](#ライセンス) - - [連絡先とサポート](#連絡先とサポート) -
+目次(クリックして展開) + +- [Markdown Viewer について](#markdown-viewer-について) +- [主な機能](#主な機能) +- [クイックスタート](#クイックスタート) +- [ローカル処理とネットワーク処理](#ローカル処理とネットワーク処理) +- [メディアの保存](#メディアの保存) +- [主な制限](#主な制限) +- [プライバシー上の重要事項](#プライバシー上の重要事項) +- [ドキュメント](#ドキュメント) +- [ショーケースプロジェクト](#ショーケースプロジェクト) +- [開発の歩み](#開発の歩み) +- [コントリビューター](#コントリビューター) +- [コントリビューションとライセンス](#コントリビューションとライセンス) ---- + -## プロジェクト概要 +## Markdown Viewer について -**Markdown Viewer** は、`.md` と `.markdown` ファイル向けのオープンソースのブラウザー型 Markdown エディター兼ビューアーです。プレーンテキスト Markdown 編集、GitHub 風ライブプレビュー、文書タブ、diagram-as-code、数式、エクスポート、共有、Web/デスクトップ展開をまとめて扱えます。 +Markdown Viewer は、開発者、ライター、学生、研究者など、`.md`/`.markdown` ファイルを扱うすべての人に向けたオープンソースのローカルファーストワークスペースです。単なるプレーンテキストにとどまりません。複数の文書を整理し、Markdown を変更せずにコメントや提案でレビューし、図表、地図、チャート、数式、3D モデル、音楽をひとつの集中できるワークスペースで描画できます。 -多くの編集、プレビュー、自動保存、ローカルファイルの読み込み、設定、エクスポートは利用者の端末上で行われます。ネットワークを使う機能は明示されています。ログインは不要です。 +文書を Share Snapshot リンクにしてすばやく共有したり、アクセス制御付きの Live Share でリアルタイム共同編集、ライブカーソル、コメント、提案を利用したりできます。通常の編集は端末上で行われます。アカウントは不要で、アプリケーションには広告、分析、テレメトリ、サブスクリプションがありません。

- Markdown Viewer - GFM レンダリング、複数文書タブワークスペース、ダークテーマに対応した分割画面ライブ Markdown エディターとプレビュー + Markdown Viewer のアプリケーション画面

-## すぐに試す - -1. [オンライン Markdown エディター](https://markdownviewer.pages.dev/) を開きます。 -2. `.md` または `.markdown` ファイルをドラッグするか、そのまま書き始めます。 -3. 必要に応じてライブプレビュー、**Insert Diagram & More**、エクスポート、Share Snapshot、Live Share を使います。 - -詳しくは Wiki の [機能](../wiki/Features.md#product-summary)、[プライバシー](../wiki/Home.md#privacy-at-a-glance)、[共有](../wiki/Features.md#share-markdown-with-snapshot-links)、[エクスポート](../wiki/Features.md#export-markdown-to-pdf-html-png-and-md)、[デスクトップ](../wiki/Features.md#desktop-app) を参照してください。 - ## 主な機能 -Markdown Viewer は基本的な Markdown 機能に加え、技術文書をより豊かに作るための機能を備えています。 - -1. **GitHub-Flavored Markdown (GFM)**: 通常の Markdown を書きながら、表、タスクリスト、取り消し線、自動リンク、コードブロック、アラート、脚注、ライブプレビューを利用できます。多くの Markdown エディターは基本機能を備えていますが、以下の機能は Markdown Viewer がより豊かな技術文書のために追加しているものです。 -2. **Advanced Diagram Support & More**: 1 つの **Insert Diagram & More** ボタンから、ビジュアルテンプレート、プレビュー、挿入できるサンプルを開けるため、すべての構文を覚えなくても複雑なコンテンツを追加できます。 - - - **Mermaid**: フローチャート、シーケンス図、ガントチャート、状態図、ドキュメント向けのアーキテクチャ可視化を作成できます。 - - **PlantUML**: ソフトウェア設計メモ向けに、シーケンス図、クラス図、ユースケース図、エンジニアリング図を追加できます。 - - **Graphviz**: ツリー、依存関係マップ、ネットワーク関係のための DOT グラフをレンダリングできます。 - - **D2**: モダンなレイアウト出力で、読みやすい diagram-as-code を作成できます。 - - **Vega-Lite**: Markdown の中でチャートやデータ可視化を直接記述できます。 - - **Markmap**: ネストした Markdown リストを、計画や学習メモ向けのマインドマップに変換できます。 - - **WaveDrom**: ハードウェアやプロトコル作業向けに、タイミング図と信号波形を記録できます。 - - **Map**: 文書を離れずに GeoJSON と TopoJSON データをプレビューできます。 - - **STL 3D Model Renderer**: 技術メモと一緒に 3D モデルをプレビュー。 - - **ABC Music Player & Sheet Music Viewer**: 楽譜レンダリングとブラウザー再生。 - -3. **文書エクスプローラーと 2 文書分割表示**: 最大 50 件の保存済みファイルをネストしたフォルダーで整理し、一括操作を使い、2 つの文書を並べて Markdown、数式、図表、地図、STL、ABC 記譜まで完全にレンダリングできます。 -4. **Comments & Suggestions**: Markdown ソースを変更せずに、レンダリング済みの文書ブロックへフィードバックを追加し、管理、解決できます。 -5. **Live Share Temporary Rooms**: サーバーで確認されるホスト、編集可能、閲覧専用の権限を使って、短時間の編集、レビュー、ペアライティングをリアルタイムに行えます。 -6. **Share Snapshot Links**: 文書の状態をすばやく送るときに、読み取り専用または編集可能な時点リンクを作成できます。保存された大きなスナップショットは 90 日後に期限切れになります。 -7. **LaTeX Math Notation**: MathJax でインライン数式と表示数式をレンダリングでき、数式の多いメモ、論文、技術説明に便利です。 -8. **Markdown to PDF, HTML & PNG Export**: 共有、印刷、アーカイブが必要な文書向けに、Markdown、HTML、PNG、Browser Print / Save as PDF、Legacy Raster PDF をエクスポートできます。 -9. **プライバシーとセキュリティの管理**: ワークスペース設定で Private mode を有効にすると、文書とレビューデータをセッション中だけ保持できます。プレビューはサニタイズされ、エクスポート HTML は保護され、デスクトップのネイティブ API は制限されています。 - -詳細、制限、プライバシーについては [機能リファレンス](../wiki/Features.md#product-summary) を参照してください。 - -## Markdown 編集とライブプレビュー - -- プレーン Markdown を書きながら、GFM、シンタックスハイライト、数式、アラート、脚注、表、タスクリスト、サニタイズ済み HTML をライブプレビューできます。 -- レスポンシブなエクスプローラーで最大 50 件の保存済み Markdown ファイルを整理できます。固定された Workspace と Secret Workspace、ネストしたフォルダー、検索、最近使った項目、お気に入り、ドラッグ&ドロップ移動、ホバー展開、端での自動スクロールに対応します。Secret Workspace の内容は端末上でパスワード暗号化されます。 -- ファイルメニューから 2 つの文書を並べて開けます。共通の操作で両側を Edit と Preview の間で切り替え、Preview では Markdown、数式、Mermaid とリモート図表、地図、STL モデル、ABC 記譜をレンダリングできます。エクスプローラーでは複数ファイルをまとめて開く、移動する、削除する操作ができ、空白領域や文書領域の右クリックから関連操作を開けます。 -- エディターのカーソル位置に画像、アニメーション GIF、MP4、WebM、Ogg 動画を貼り付け、アップロード、またはドロップできます。進行状況トーストがアップロード状態を示し、管理対象メディアは短いコンテンツアドレス型 HTTPS リンクとして、再読み込み、Share Snapshot、Live Share、Markdown エクスポート後も 90 日の期限まで利用できます。同じ初回同意の後、既存のインラインラスター画像も変換できます。 -- WYSIWYG 風ツールバーで入力を補助しつつ、Markdown ソースはそのまま管理できます。 -- 大きな文書はデバウンス処理とバックグラウンド Worker でプレビューし、入力の応答性を保ちます。 - -## 図表とビジュアルコンテンツ - -Markdown Viewer は、技術メモ、ドキュメント、ハードウェア記事、音楽スニペット、データ中心の文書に使える Markdown 図表エディターとしても役立ちます。 - -- **Mermaid、PlantUML、Graphviz / DOT、D2**: フローチャート、シーケンス図、クラス図、アーキテクチャスケッチ、依存関係グラフ、diagram-as-code ワークフロー向け。 -- **Vega-Lite、Markmap**: Markdown チャート、データ可視化、マインドマップ向け。 -- **WaveDrom**: タイミング図と信号ドキュメント向け。 -- **GeoJSON、TopoJSON マップ**: 位置情報を含む Markdown 文書向け。 -- **STL 3D モデルプレビュー**: メモと並べて 3D モデルスニペットを確認する用途向け。 -- **ABC 記譜**: 楽譜レンダリングとブラウザー再生向け。 +- **ワークスペースと文書:** 最大 50 件の文書をネストしたフォルダーに整理できます。最近使ったファイル、お気に入り、検索、タブ、一括操作、暗号化された Secret Workspace(秘密のワークスペース)に対応します。 +- **編集とレビュー:** エディター、分割表示、プレビューを切り替えられます。書式設定ツール、独自の元に戻す/やり直す、検索と置換、LTR/RTL、コメント、提案を利用できます。 +- **Markdown 描画:** CommonMark 形式の基本構文、GitHub-Flavored Markdown(GFM)、表、タスクリスト、アラート、脚注、定義リスト、コードのシンタックスハイライト、サニタイズ済み HTML、MathJax に対応します。 +- **ビジュアルコンテンツ:** Mermaid、PlantUML、Graphviz/DOT、D2、Vega-Lite、WaveDrom、Markmap、GeoJSON、TopoJSON、STL、ABC 記譜を描画できます。

- 図表サポートとその他の機能 - ABC 音楽記譜と音声合成 - STL 3D モデルレンダラー + 図表挿入モジュール + 図表の描画例 + 3D STL ビュー + 全画面の 3D STL ビュー

-## 共有、共同編集、エクスポート +- **インポートとエクスポート:** ローカルファイルや公開 GitHub コンテンツを開き、Markdown、単体 HTML、PNG、ブラウザー印刷/PDF 保存、従来のラスター PDF として出力できます。 +- **任意の共有機能:** 「表示のみ」または「編集可能」の Share Snapshot(スナップショットの共有)を作成したり、ホスト/編集可能/表示のみの権限を持つ一時的な Live Share(ライブシェア)ルームを開始したりできます。 -- **Comments & Suggestions** は、Markdown を変更せずに、レンダリング済みの YAML、見出し、段落、コードブロック、図へレビュー層を追加します。フィードバックは追加、編集、解決、再開、削除、コピーができ、通常のタブに保存され、アクティブな Live Share ルームでのみ同期されます。 -- **Share Snapshot** は、時点 Markdown 共有用のすばやいリンクを作成します。小さな文書は URL hash に保持でき、より大きなスナップショットは、そのバックエンドが構成されている場合に Cloudflare KV へ最大 90 日間一時保存されます。リンクを持つ人は誰でも開けます。

- Share Snapshot + Live Share セッション

-- **Live Share rooms** は Cloudflare Durable Objects を使った一時的な共同編集機能で、ホスト、編集可能、閲覧専用の権限をサーバーが確認します。レビューやペアライティングに便利ですが、エンドツーエンド暗号化ではありません。 -

- Live Share rooms -

- -- **Markdown export** は元の `.md` 文書をダウンロードします。 -- **HTML export** は単体で開けるレンダリング済み文書を作成します。 -- **PDF export** はブラウザー印刷/Save as PDF と Legacy Raster PDF に対応します。 -- **PNG export** はレンダリング済みプレビューを画像として保存します。 - ---- - -## システム構成 - -Markdown Viewer はクライアント側のシングルページアプリです。`script.js` が UI を制御し、`preview-worker.js` が Markdown をバックグラウンドでコンパイルし、`sw.js` がオフライン対応キャッシュを扱います。 - -### 主要ファイル +- **複数の提供形態:** ホスト済み Web アプリ、PWA、静的ホスティング、Docker、Cloudflare、Neutralino デスクトップアプリケーションを利用できます。 -1. **`index.html`**: アプリのレイアウトとスクリプト/スタイルの入口。 -2. **`script.js`**: タブ、編集状態、プレビュー更新、インポート、エクスポート、共有、UI 動作。 -3. **`styles.css`**: レイアウト、テーマ、プレビュー、印刷スタイル。 -4. **`preview-worker.js`**: Markdown 解析とシンタックスハイライト。 -5. **`sw.js`**: オフライン対応のアセットキャッシュ。 +実装済みの動作と制限は、[機能リファレンス(英語)](../wiki/Features.md)を参照してください。 ---- +## クイックスタート -## 開始方法とインストール +[ホスト済み Web アプリ](https://markdownviewer.pages.dev/)を利用するか、リポジトリをローカル HTTP サーバーで起動します。 -### 💻 方法 1: ローカルですぐに実行(インストール不要) - -`index.html` を `file://` で直接開くのではなく、ローカル HTTP サーバー経由で実行してください。 - -1. リポジトリをクローンまたはダウンロードします。 -2. リポジトリフォルダーでターミナルを開きます。 -3. `python -m http.server 8080` または `npx serve . -p 8080` を実行します。 -4. ブラウザーで **[http://localhost:8080](http://localhost:8080)** を開きます。 - ---- - -### 🐳 方法 2: Docker コンテナー - -コンテナーでアプリを実行します。 - -**事前ビルド済み Docker イメージ(GHCR):** -```bash -docker run -d \ - --name markdown-viewer \ - -p 8080:80 \ - --restart unless-stopped \ - ghcr.io/thisis-developer/markdown-viewer:latest -``` - -ブラウザーで **[http://localhost:8080](http://localhost:8080)** を開きます。 - -**ローカル Docker Compose ビルド:** ```bash git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git cd Markdown-Viewer -docker compose up -d -``` -ブラウザーで **[http://localhost:8080](http://localhost:8080)** を開きます。 - ---- - -### 🖥️ 方法 3: デスクトップアプリのビルド - -ソースから Neutralinojs デスクトップアプリをビルドします。 - -1. リポジトリをクローンし、`desktop-app/` ディレクトリへ移動します。 - ```bash - cd desktop-app - ``` -2. 依存関係をインストールしてビルドします。 - ```powershell - npm install - npm run build - ``` - -`npm run build` は必要な Neutralino バイナリをダウンロードし、ローカルリソースを準備して、7 つの自己完結型プラットフォーム実行ファイルを作成します。 - -ビルド済みバイナリは [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) から入手できます。 - ---- - -## 使い方とキーボードショートカット - -ワークフロー、編集操作、エクスポート、共有、ショートカットは [使い方ガイド](../wiki/Usage-Guide.md#workspace-layout-for-editing-and-previewing-markdown) を参照してください。 - ---- - -## プロジェクトディレクトリ構成 - -```text -Markdown-Viewer/ -+-- index.html # Web アプリ本体 -+-- script.js # アプリロジックと UI 制御 -+-- styles.css # アプリとプレビューのスタイル -+-- preview-worker.js # Markdown プレビュー Worker -+-- sw.js # Service Worker キャッシュ -+-- assets/ # アプリの画像とアイコン -| +-- i18n/ # UI 翻訳カタログと生成ツール -+-- functions/ # Cloudflare Pages Functions -+-- workers/ # Live Share Worker ソース -+-- desktop-app/ # Neutralinojs デスクトップ版 -+-- locales/ # ローカライズ済み README -+-- wiki/ # プロジェクト文書 -+-- Dockerfile # Docker イメージ設定 -+-- docker-compose.yml # ローカルコンテナー設定 -+-- wrangler.toml # Cloudflare デプロイ設定 -+-- README.md # プロジェクト概要 -+-- CHANGELOG.md # リリース履歴 -+-- LICENSE # Apache License 2.0 +python -m http.server 8080 ``` ---- +`http://localhost:8080` を開きます。`file://` では Web Worker や Service Worker がブラウザーにブロックされる場合があります。 -## Built With(技術スタック) +| 利用方法 | 詳細(英語) | +| :--- | :--- | +| PWA/静的 Web ホスティング | [インストール](../wiki/Installation.md) | +| Docker | [Docker デプロイ](../wiki/Docker-Deployment.md) | +| Cloudflare Pages/KV/Durable Objects | [設定](../wiki/Configuration.md) | +| Neutralino デスクトップアプリケーション | [デスクトップアプリケーション](../wiki/Desktop-App.md) | -

- HTML5 - CSS3 - JavaScript - Bootstrap - NeutralinoJS -

+## ローカル処理とネットワーク処理 + +Markdown Viewer はローカルファーストですが、すべての機能がオフラインで動作するわけではありません。 + +| 操作 | 既定のデータ経路 | +| :--- | :--- | +| 編集、ローカルインポート、プレビュー、ワークスペースの自動保存、ほとんどのエクスポート | 端末上 | +| Web ライブラリと未キャッシュのレンダラー依存関係 | Web/PWA 版から CDN へ接続 | +| GitHub インポートと絵文字検索 | GitHub API/raw コンテンツ | +| PlantUML、D2、Graphviz、Vega-Lite、WaveDrom、一部の図表プレビュー | 図表ソースを PlantUML、Kroki、mermaid.ink に送信する場合あり | +| 同意後に挿入する画像、GIF、動画 | 公開リンク型の Cloudflare 一時メディアストレージ(90 日) | +| 大きな Share Snapshot | Cloudflare KV(90 日) | +| Live Share | Cloudflare Durable Object の WebSocket リレー | +| 外部画像、メディア、リンク、地図タイル | 文書で指定された外部ホスト | -主な技術スタック: HTML、CSS、JavaScript、Bootstrap、Bootstrap Icons、Neutralinojs、Marked.js、Highlight.js、DOMPurify、MathJax、Mermaid、Leaflet、Three.js、ABCJS、Markmap、Yjs、jsPDF、html2canvas、Cloudflare Pages/Workers。 +Share Snapshot と Live Share の URL はベアラーリンクです。有効なリンクを入手した人は、そのリンクに含まれる権限を利用できます。Live Share はエンドツーエンド暗号化されていません。機密性の高い文書を扱う前に、[プライバシーとセキュリティ(英語)](../wiki/Privacy-and-Security.md)を確認してください。 -依存関係の読み込み、CDN 利用、デスクトップ用ローカルライブラリについては [クライアントライブラリの説明](../wiki/Configuration.md#client-libraries) を参照してください。 +## メディアの保存 -一部の高度な図表エンジンは PlantUML、Kroki、mermaid.ink などのリモートレンダラーを使います。挙動とプライバシーの詳細は [図表レンダラーの説明](../wiki/Features.md#insert-diagrams-charts-maps-models-and-music) を参照してください。 +- AVIF、BMP、GIF(アニメーション GIF を含む)、JPEG、PNG、WebP、MP4、WebM、Ogg を挿入できます。 +- 初回の同意後、メディアは Cloudflare の一時ストレージにアップロードされ、短いコンテンツアドレス型 HTTPS URL として挿入されます。 +- URL を知っている人は誰でも、期限が切れるまでメディアを取得できます。 +- 同一コンテンツを最後にアップロードしてから 90 日後に期限切れになります。 +- Share Snapshot と Live Share は Markdown 内の URL を共有します。メディアの別コピーは作成しません。 ---- +## 主な制限 -## プライバシー +- ワークスペースは最大 50 文書です。ロック中の Secret Workspace の件数と一時的な Share Snapshot/Live Share タブも含まれます。 +- 1 件のローカル Markdown ファイルは 10 MB までです。 +- GitHub インポーターが表示する Markdown ファイルは、リポジトリ/フォルダーごとに最大 30 件です。 +- メディアの元ファイルは処理前で 25 MiB までです。保存上限は静止画 300 KiB、GIF 5 MiB、動画 10 MiB です。 +- 保存型 Share Snapshot は最大 8,000,000 文字で、90 日後に期限切れになります。 +- Live Share は最大 64 WebSocket 参加者、1 メッセージ 8 MB までです。 +- STL はソース 2 MiB、描画ジオメトリ 300,000 頂点までです。 +- ラスター PDF/PNG はブラウザーのメモリ、Canvas、CORS の制約を受けます。 -Markdown Viewer はクラウドワークスペースではありません。通常の入力、プレビュー、ローカルファイル読み込み、タブの自動保存、テーマ設定、多くのエクスポートは端末上で行われます。ログインは不要で、分析、テレメトリ、広告、追跡 Cookie は実装していません。 +## プライバシー上の重要事項 -ネットワーク利用は、同意後の管理対象メディアのアップロード、GitHub インポート、リモート図表レンダラー、Share Snapshot、Live Share、CDN ライブラリ、外部文書リソースなど、ユーザーが使う機能に限られます。ワークスペース設定の Private mode を使うと、編集とレビュー機能を保ったまま、文書内容、ワークスペース状態、レビューフィードバックをセッション中だけ保持できます。詳細は [データ処理の概要](../wiki/Features.md#data-handling-summary) を参照してください。 +- 通常のワークスペースデータは、ブラウザープロファイルまたはデスクトップのローカルストレージに保存されます。 +- プライベートモードを有効にすると、Secret Workspace の暗号化済みデータを含む永続化済み文書データが消去され、その後の保存が停止します。 +- **ワークスペースをリセット**すると、通常文書、レビューデータ、Secret Workspace データが削除されます。Markdown Viewer からは復元できません。 +- Live Share は Markdown/レビューデータをサーバー側に永続保存しません。ただし、役割別のベアラー権限値と作成時刻は Durable Object ストレージに保存され、アプリケーション側の有効期限/削除経路はありません。 +- Share Snapshot の作成 API は削除トークンを返しますが、現在の UI はそのトークンを表示せず、期限前の削除操作も提供していません。 +- アプリケーションコードには、アカウント、分析、テレメトリ、広告、トラッキングピクセル、アプリ固有 Cookie は実装されていません。外部サービスやホスティング事業者は通常のリクエストログを処理する場合があります。 -## セキュリティとプライバシーの管理 +> **警告:** プライベートモードまたは **ワークスペースをリセット**を使用する前に、必要な文書を Markdown としてエクスポートしてください。 -- プレビュー HTML は挿入前にサニタイズされます。エクスポート HTML には制限の厳しい CSP と、外部アセット用の SRI メタデータが含まれます。 -- Secret Workspace は PBKDF2-SHA-256 でパスワードからローカル鍵を生成し、AES-GCM でファイルとフォルダー名を暗号化します。鍵はロック解除中のセッションだけに保持され、忘れたパスワードは復元できません。 -- Cloudflare Pages は `_headers` を使い、CSP、クリックジャッキング対策、リファラーポリシー、権限ポリシー、MIME スニッフィング対策を適用します。機密パスは 404 にリダイレクトされます。 -- 管理対象メディアと保存型 Share Snapshot API のアップロード元は、本番アプリ、プレビュー、`null`、ローカル開発環境に制限されます。画像、GIF、動画は推測しにくい公開リンクで 90 日間取得できます。スナップショット応答は `no-store` で、作成者には削除トークンが返されます。 -- STL レンダリングは WebGL 処理前に、サイズ超過、有限でない形状、頂点数超過を拒否します。 -- Neutralino デスクトップ版は既定の `os.execCommand` を公開せず、ネイティブ API を明示的な許可リストに限定します。詳しくは [セキュリティモデル](../wiki/Features.md#security-model) と [設定リファレンス](../wiki/Configuration.md#share-api) を参照してください。 +## ドキュメント ---- +詳細ページは英語で管理されています。 -## コントリビューションとコード品質 +| 目的 | ページ(英語) | +| :--- | :--- | +| 全機能と制限 | [Features](../wiki/Features.md) | +| 日常の操作とショートカット | [Usage Guide](../wiki/Usage-Guide.md) | +| Markdown/図表の構文 | [Markdown Reference](../wiki/Markdown-Reference.md) | +| Share Snapshot | [Share Snapshot](../wiki/Share-Snapshot.md) | +| Live Share | [Live Share](../wiki/Live-Share-Cloudflare.md) | +| プライバシーとセキュリティ | [Privacy and Security](../wiki/Privacy-and-Security.md) | +| インストールとデプロイ | [Installation](../wiki/Installation.md) | +| トラブルシューティング | [Troubleshooting](../wiki/Troubleshooting.md)/[FAQ](../wiki/FAQ.md) | +| コントリビューション | [Contributing](../wiki/Contributing.md) | +| 多言語用語とローカライズ | [Localization and Terminology](../wiki/Localization.md) | -コミュニティからの貢献を歓迎します。Pull Request を作成する前に [コード変更前のコントリビューションガイド](../wiki/Contributing.md#before-changing-code) を確認してください。 +## ショーケースプロジェクト -### コアワークフロー概要: -1. **Fork** して機能ブランチを作成します(`git checkout -b feature/your-feature`)。 -2. **コードスタイルを確認:** HTML、CSS、JS ファイル全体で、きれいな 2 スペースインデントを維持してください。生の HTML 構造はセマンティックにしてください。処理 Worker 内で直接 DOM クエリを行うことは避けてください。 -3. **Conventional Commits:** `feat:`、`fix:`、`docs:`、`style:`、`refactor:`、`perf:`、`chore:` のいずれかを付けた明確なコミットメッセージを書いてください。 -4. **テスト:** Chrome、Firefox、Edge、Safari の各ビューポートで変更をテストしてください。 +Markdown Viewer を活用した以下のコミュニティプロジェクトは、各開発者によって独立して保守されています。 ---- +- [**Markdown Desk**](https://github.com/jhrepo/markdown-desk):Tauri で構築された macOS 向けネイティブラッパーです。ネイティブのファイルダイアログとファイルハンドラー、メニューバー連携、自動再読み込み、アプリ内更新を追加します。 -## ショーケースとコミュニティプロジェクト +## 開発の歩み -* **[Markdown Desk](https://github.com/jhrepo/markdown-desk):** Tauri で作られたネイティブ macOS ラッパーで、ネイティブファイルシステムハンドラー、メニューバー統合、自動リロード機能を追加します。 +Markdown Viewer は、PC 上の小さな個人プロジェクトとして始まりました。好奇心を出発点に、失敗と修正を重ね、多くの配慮を込めて作られたシンプルな Markdown ビューアーです。初期バージョンは今も公開されており、プロジェクトの原点であり続けています。 ---- +詳しい歴史は [Development Journey(英語)](../wiki/Development-Journey.md)をご覧ください。 ## コントリビューター -Markdown Viewer に貢献してくださったすべての方に感謝します。 +Markdown Viewer は、コミュニティからのコントリビューションによって成長しています。 - Contributors + Markdown Viewer のコントリビューター ---- - -## 📈 開発の歩み - -Markdown Viewer は PC 上の小さな個人プロジェクトとして始まりました。好奇心、失敗、修正、そして多くの思いやりから作られた、シンプルな Markdown ビューアーでした。最初のバージョン は今もオンラインで、このプロジェクトの原点として残っています。 - -現在の Markdown Viewer は、コミュニティからのフィードバック、Issue、PR、スクリーンショット、GIF、提案、実際の文書作成ワークフローを通じて育ちました。技術的な進歩も大切ですが、この歩みには感情的な側面もあります。多くの人が、このアプリを現在の姿に形作る手助けをしてくれました。 - ---- - -## ライセンス - -このプロジェクトは Apache License 2.0 のもとで公開されています。完全な条項と条件については [LICENSE](../LICENSE) を参照してください。 - ---- - -## 連絡先とサポート +## コントリビューションとライセンス -開発と保守: **[ThisIs-Developer](https://github.com/ThisIs-Developer)** +Pull Request を作成する前に、[Contributing(英語)](../wiki/Contributing.md)を確認してください。再現可能な不具合や明確な機能提案は [Issue Tracker](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) に報告できます。脆弱性の詳細は通常の Issue に投稿しないでください。 -* **バグ報告と要望:** [Issue を送信](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) -* **ドキュメント:** [Wiki の案内](../wiki/Home.md#start-here) +Markdown Viewer は [Apache License 2.0](../LICENSE) で提供されています。 diff --git a/locales/README_ko.md b/locales/README_ko.md index 536e8c8e..1d08a30e 100644 --- a/locales/README_ko.md +++ b/locales/README_ko.md @@ -1,339 +1,189 @@
- Markdown Viewer Logo + Markdown Viewer 로고 -

Markdown Viewer - 실시간 미리보기가 있는 온라인 Markdown 에디터

+

Markdown Viewer

- **브라우저 기반 Markdown 에디터, 뷰어, 프리뷰어, 리더입니다.** + **실시간 미리보기를 제공하는 로컬 우선 Markdown 편집기 및 뷰어** - *`.md` 파일을 열고, 읽고, 편집하고, 분할 화면 실시간 Markdown 미리보기, 동기화 스크롤, GitHub-Flavored Markdown, 다이어그램, 지도, 3D STL 미리보기, ABC 악보 재생, PDF/HTML/PNG 내보내기, Web/데스크톱/Docker의 다중 탭 작업을 지원합니다.* + 브라우저, 프로그레시브 웹 앱(PWA), Docker 또는 Neutralino 데스크톱 애플리케이션에서 Markdown을 열고 작성하고 정리하고 검토하고 렌더링하고 내보낼 수 있습니다. 필요한 경우 공유와 공동 편집도 사용할 수 있습니다. - [![License](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/LICENSE) - [![Latest Release](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) - [![Last Commit](https://img.shields.io/github/last-commit/ThisIs-Developer/Markdown-Viewer?style=flat-square)](https://github.com/ThisIs-Developer/Markdown-Viewer/commits/main) - [![Stars](https://img.shields.io/github/stars/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=dfb317)](https://github.com/ThisIs-Developer/Markdown-Viewer/stargazers) + [![라이선스](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](../LICENSE) + [![최신 릴리스](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)

- CodeWiki + CodeWiki에서 Markdown Viewer 살펴보기 - DeepWiki + DeepWiki에서 Markdown Viewer 살펴보기

- 🌐 [English](../README.md) • [简体中文](README_zh.md) • [日本語](README_ja.md) • **한국어** • 더 많은 언어 + [English](../README.md) · [日本語](README_ja.md) · **한국어** · [简体中文](README_zh.md) · [繁體中文](README_tw.md) - [라이브 데모](https://markdownviewer.pages.dev/) • [Wiki](../wiki/Home.md#start-here) • [이슈 추적기](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) • [릴리스](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + [웹 앱 열기](https://markdownviewer.pages.dev/) · [문서(영어)](../wiki/Home.md) · [이슈 보고](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) · [릴리스](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)
-## 목차 -
- 📂 목차 (클릭하여 펼치기) -
- - - [프로젝트 소개](#프로젝트-소개) - - [빠르게 사용해 보기](#빠르게-사용해-보기) - - [주요 기능](#주요-기능) - - [Markdown 편집과 실시간 미리보기](#markdown-편집과-실시간-미리보기) - - [다이어그램과 시각 콘텐츠](#다이어그램과-시각-콘텐츠) - - [공유, 협업, 내보내기](#공유-협업-내보내기) - - [시스템 구조](#시스템-구조) - - [핵심 파일](#핵심-파일) - - [시작하기와 설치](#시작하기와-설치) - - [사용 가이드와 키보드 단축키](#사용-가이드와-키보드-단축키) - - [프로젝트 디렉터리 구조](#프로젝트-디렉터리-구조) - - [Built With (기술 스택)](#built-with-기술-스택) - - [개인정보](#개인정보) - - [보안 및 개인정보 보호](#보안-및-개인정보-보호) - - [기여와 코드 품질](#기여와-코드-품질) - - [쇼케이스와 커뮤니티 프로젝트](#쇼케이스와-커뮤니티-프로젝트) - - [기여자](#기여자) - - [📈 개발 여정](#-개발-여정) - - [라이선스](#라이선스) - - [연락처와 지원](#연락처와-지원) -
+목차(클릭하여 펼치기) + +- [Markdown Viewer 소개](#markdown-viewer-소개) +- [주요 기능](#주요-기능) +- [빠른 시작](#빠른-시작) +- [로컬 처리와 네트워크 처리](#로컬-처리와-네트워크-처리) +- [미디어 저장 방식](#미디어-저장-방식) +- [주요 제한](#주요-제한) +- [개인정보 관련 중요 사항](#개인정보-관련-중요-사항) +- [문서](#문서) +- [쇼케이스 프로젝트](#쇼케이스-프로젝트) +- [개발 여정](#개발-여정) +- [기여자](#기여자) +- [기여 및 라이선스](#기여-및-라이선스) ---- + -## 프로젝트 소개 +## Markdown Viewer 소개 -**Markdown Viewer**는 `.md` 및 `.markdown` 파일을 위한 오픈 소스 브라우저 기반 Markdown 에디터이자 뷰어입니다. 일반 텍스트 Markdown 편집, GitHub 스타일 실시간 미리보기, 문서 탭, diagram-as-code 도구, 수식, 내보내기, 공유, Web/데스크톱 배포 옵션을 함께 제공합니다. +Markdown Viewer는 개발자, 작성자, 학생, 연구자 등 `.md` 또는 `.markdown` 파일을 사용하는 모든 사람을 위한 오픈 소스 로컬 우선 작업공간입니다. 단순한 텍스트를 넘어 여러 문서를 정리하고, Markdown을 변경하지 않은 채 댓글과 제안으로 검토하며, 다이어그램, 지도, 차트, 수식, 3D 모델, 음악을 하나의 집중된 작업공간에서 렌더링할 수 있습니다. -대부분의 편집, 미리보기, 자동 저장, 로컬 파일 가져오기, 설정, 내보내기는 사용자의 기기에서 처리됩니다. 네트워크 기능은 명확히 설명되어 있습니다. 로그인은 필요하지 않습니다. +문서를 Share Snapshot 링크로 만들어 빠르게 공유하거나, 접근 권한이 제어되는 Live Share에서 실시간 공동 편집, 라이브 커서, 댓글, 제안을 사용할 수 있습니다. 일상적인 편집은 기기에서 처리됩니다. 계정이 필요 없으며 애플리케이션에는 광고, 분석, 원격 측정 또는 구독이 없습니다.

- Markdown Viewer - GFM 렌더링, 다중 문서 탭 작업 공간, 다크 테마를 지원하는 분할 화면 실시간 Markdown 에디터와 미리보기 + Markdown Viewer 애플리케이션 화면

-## 빠르게 사용해 보기 - -1. [온라인 Markdown 에디터](https://markdownviewer.pages.dev/)를 엽니다. -2. `.md` 또는 `.markdown` 파일을 끌어오거나 바로 작성합니다. -3. 필요에 따라 실시간 미리보기, **Insert Diagram & More**, 내보내기 메뉴, Share Snapshot, Live Share를 사용합니다. - -자세한 내용은 Wiki의 [기능](../wiki/Features.md#product-summary), [개인정보](../wiki/Home.md#privacy-at-a-glance), [공유](../wiki/Features.md#share-markdown-with-snapshot-links), [내보내기](../wiki/Features.md#export-markdown-to-pdf-html-png-and-md), [데스크톱](../wiki/Features.md#desktop-app) 섹션을 참고하세요. - ## 주요 기능 -Markdown Viewer는 기본 Markdown 기능을 지원하면서, 더 풍부한 기술 문서를 작성할 수 있게 도와줍니다. - -1. **GitHub-Flavored Markdown (GFM)**: 일반 Markdown을 작성하면서 표, 작업 목록, 취소선, 자동 링크, 코드 블록, 알림 블록, 각주, 실시간 미리보기를 사용할 수 있습니다. 대부분의 Markdown 편집기는 기본 기능을 다루지만, 아래 기능들은 Markdown Viewer가 더 풍부한 기술 문서를 위해 제공하는 추가 기능입니다. -2. **Advanced Diagram Support & More**: 하나의 **Insert Diagram & More** 버튼으로 시각 템플릿, 미리보기, 바로 삽입할 수 있는 예제를 열 수 있어 사용자가 모든 문법을 외우지 않아도 복잡한 콘텐츠를 추가할 수 있습니다. - - - **Mermaid**: 플로차트, 시퀀스 다이어그램, 간트 차트, 상태도, 문서 친화적인 아키텍처 시각화를 만들 수 있습니다. - - **PlantUML**: 소프트웨어 설계 노트에 시퀀스, 클래스, 유스케이스, 엔지니어링 다이어그램을 추가할 수 있습니다. - - **Graphviz**: 트리, 의존성 맵, 네트워크 관계를 위한 DOT 그래프를 렌더링할 수 있습니다. - - **D2**: 현대적인 레이아웃 출력으로 깔끔한 diagram-as-code를 만들 수 있습니다. - - **Vega-Lite**: Markdown 안에서 차트와 데이터 시각화를 직접 설명할 수 있습니다. - - **Markmap**: 중첩 Markdown 목록을 계획과 학습 노트에 적합한 마인드맵으로 바꿀 수 있습니다. - - **WaveDrom**: 하드웨어나 프로토콜 작업을 위한 타이밍 다이어그램과 신호 파형을 문서화할 수 있습니다. - - **Map**: 문서를 벗어나지 않고 GeoJSON 및 TopoJSON 데이터를 미리볼 수 있습니다. - - **STL 3D Model Renderer**: 기술 노트 옆에서 3D 모델 미리보기. - - **ABC Music Player & Sheet Music Viewer**: 악보 렌더링과 브라우저 재생. - -3. **문서 탐색기 및 두 문서 분할 보기**: 중첩 폴더에 저장된 파일을 최대 50개까지 정리하고, 일괄 파일 작업을 사용하며, 두 문서를 나란히 열어 Markdown, 수식, 다이어그램, 지도, STL, ABC 기보를 모두 렌더링할 수 있습니다. -4. **Comments & Suggestions**: Markdown 소스를 변경하지 않고 렌더링된 문서 블록에 피드백을 추가하고 관리하며 해결할 수 있습니다. -5. **Live Share Temporary Rooms**: 서버가 확인하는 호스트, 편집 가능, 보기 전용 권한으로 빠른 편집 세션, 리뷰, 페어 작성에 사용할 수 있는 실시간 협업 공간입니다. -6. **Share Snapshot Links**: 문서 상태를 빠르게 보내야 할 때 읽기 전용 또는 편집 가능한 특정 시점 링크를 만들 수 있습니다. 저장된 큰 스냅샷은 90일 후 만료됩니다. -7. **LaTeX Math Notation**: MathJax로 인라인 및 표시 수식을 렌더링하며, 수식이 많은 노트, 논문, 기술 설명에 유용합니다. -8. **Markdown to PDF, HTML & PNG Export**: 공유, 인쇄, 보관이 필요한 문서를 위해 Markdown, HTML, PNG, Browser Print / Save as PDF, Legacy Raster PDF를 내보낼 수 있습니다. -9. **개인정보 및 보안 제어**: 작업 공간 설정에서 Private mode를 켜 문서와 리뷰 데이터를 현재 세션에만 유지할 수 있습니다. 미리보기는 정리되고, 내보낸 HTML은 보안이 강화되며, 데스크톱 네이티브 API는 제한됩니다. - -자세한 기능, 제한, 개인정보 관련 사항은 [기능 참고](../wiki/Features.md#product-summary)를 확인하세요. - -## Markdown 편집과 실시간 미리보기 - -- 일반 Markdown을 작성하면서 GFM, 구문 강조, 수식, 알림, 각주, 표, 작업 목록, 정리된 HTML을 실시간으로 미리볼 수 있습니다. -- 반응형 탐색기에서 저장된 Markdown 파일을 최대 50개까지 정리할 수 있습니다. 고정된 Workspace 및 Secret Workspace 루트, 중첩 폴더, 검색, 최근 파일, 즐겨찾기, 끌어서 놓기 이동, 폴더 자동 펼치기, 가장자리 자동 스크롤을 지원합니다. Secret Workspace 내용은 기기에서 비밀번호로 암호화됩니다. -- 파일 메뉴에서 두 문서를 나란히 열 수 있습니다. 하나의 공용 컨트롤로 양쪽을 편집과 미리보기 사이에서 전환하며, 미리보기 모드에서는 Markdown, 수식, Mermaid와 원격 다이어그램, 지도, STL 모델, ABC 기보를 렌더링합니다. 탐색기에서 파일을 여러 개 선택해 함께 열거나 이동하거나 삭제할 수 있고, 빈 영역이나 문서 영역을 마우스 오른쪽 버튼으로 클릭해 관련 작업을 열 수 있습니다. -- 편집기 커서 위치에 이미지, 애니메이션 GIF, MP4, WebM, Ogg 동영상을 붙여넣거나 업로드하거나 놓을 수 있습니다. 진행 토스트가 업로드 상태를 보여 주며, 관리형 미디어는 짧은 콘텐츠 주소형 HTTPS 링크를 사용해 새로 고침, Share Snapshot, Live Share, Markdown 내보내기 후에도 90일 만료 시점까지 사용할 수 있습니다. 같은 최초 동의 후 기존 인라인 래스터 이미지도 변환할 수 있습니다. -- WYSIWYG 스타일 툴바를 사용하면서도 일반 텍스트 Markdown 소스를 그대로 제어할 수 있습니다. -- 큰 문서는 디바운스 렌더링과 백그라운드 Worker로 미리보며, 입력이 계속 빠르게 반응하도록 합니다. - -## 다이어그램과 시각 콘텐츠 - -Markdown Viewer는 기술 노트, 문서, 하드웨어 글, 음악 스니펫, 데이터가 많은 문서를 위한 Markdown 다이어그램 편집기로도 잘 맞습니다. - -- **Mermaid, PlantUML, Graphviz / DOT, D2**: 플로차트, 시퀀스 다이어그램, 클래스 다이어그램, 아키텍처 스케치, 의존성 그래프, diagram-as-code 작업 흐름에 사용할 수 있습니다. -- **Vega-Lite, Markmap**: Markdown 차트, 데이터 시각화, 마인드맵에 사용할 수 있습니다. -- **WaveDrom**: 타이밍 다이어그램과 신호 문서화에 사용할 수 있습니다. -- **GeoJSON 및 TopoJSON 지도**: 위치 정보를 포함한 Markdown 문서에 사용할 수 있습니다. -- **STL 3D 모델 미리보기**: 노트 옆에서 3D 모델 스니펫을 확인하는 데 사용할 수 있습니다. -- **ABC notation**: 악보 렌더링과 브라우저 재생에 사용할 수 있습니다. +- **작업공간 및 문서:** 중첩 폴더에서 최대 50개 문서를 정리할 수 있습니다. 최근 파일, 즐겨찾기, 검색, 탭, 일괄 작업, 암호화된 Secret Workspace(비밀 작업 공간)를 지원합니다. +- **편집 및 리뷰:** 편집기, 분할 보기, 미리보기 사이를 전환할 수 있습니다. 서식 도구, 사용자 지정 실행 취소/다시 실행, 찾기 및 바꾸기, LTR/RTL, 댓글과 제안을 사용할 수 있습니다. +- **Markdown 렌더링:** CommonMark 스타일의 기본 구문, GitHub-Flavored Markdown(GFM), 표, 작업 목록, 알림, 각주, 정의 목록, 코드 구문 강조, 정제된 HTML, MathJax를 지원합니다. +- **시각 콘텐츠:** Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL, ABC 기보를 렌더링합니다.

- 다이어그램 지원 및 기타 기능 - ABC 음악 악보와 오디오 합성 - STL 3D 모델 렌더러 + 다이어그램 삽입 모듈 + 다이어그램 렌더링 예시 + 3D STL 보기 + 전체 화면 3D STL 보기

-## 공유, 협업, 내보내기 +- **가져오기 및 내보내기:** 로컬 파일이나 공개 GitHub 콘텐츠를 열고 Markdown, 독립 실행형 HTML, PNG, 브라우저 인쇄/PDF 저장, 레거시 래스터 PDF로 내보낼 수 있습니다. +- **선택적 공유:** 보기 전용 또는 편집 가능 모드의 Share Snapshot(스냅샷 공유)을 만들거나, 호스트/편집 가능/보기 전용 권한을 사용하는 임시 Live Share(라이브 공유) 방을 시작할 수 있습니다. -- **Comments & Suggestions**는 Markdown을 변경하지 않고 렌더링된 YAML, 제목, 문단, 코드 블록, 다이어그램에 리뷰 계층을 추가합니다. 피드백을 추가, 편집, 해결, 다시 열기, 삭제, 복사할 수 있으며 일반 탭에 저장되고 활성 Live Share 공간에서만 동기화됩니다. -- **Share Snapshot**은 특정 시점의 Markdown 공유를 위한 빠른 링크를 만듭니다. 작은 문서는 URL hash에 남길 수 있고, 더 큰 스냅샷은 해당 백엔드가 구성된 경우 Cloudflare KV에 최대 90일간 임시 저장됩니다. 링크를 가진 사람은 누구나 열 수 있습니다.

- Share Snapshot + Live Share 세션

-- **Live Share rooms**는 Cloudflare Durable Objects를 통한 임시 공동 편집을 제공하며, 서버가 호스트, 편집 가능, 보기 전용 권한을 확인합니다. 리뷰와 페어 작성에 유용하지만 엔드 투 엔드 암호화는 아닙니다. -

- Live Share rooms -

- -- **Markdown export**는 원본 `.md` 문서를 다운로드합니다. -- **HTML export**는 독립 실행 가능한 렌더링 문서를 만듭니다. -- **PDF export**는 Browser Print / Save as PDF와 Legacy Raster PDF를 포함합니다. -- **PNG export**는 렌더링된 미리보기를 이미지로 캡처합니다. - ---- - -## 시스템 구조 - -Markdown Viewer는 클라이언트 측 단일 페이지 앱입니다. `script.js`가 UI를 제어하고, `preview-worker.js`가 백그라운드에서 Markdown을 컴파일하며, `sw.js`가 오프라인 가능 캐싱을 처리합니다. - -### 핵심 파일 +- **다양한 실행 방식:** 호스팅 웹 앱, PWA, 정적 호스팅, Docker, Cloudflare 또는 Neutralino 데스크톱 애플리케이션을 사용할 수 있습니다. -1. **`index.html`**: 앱 레이아웃과 스크립트/스타일 진입점. -2. **`script.js`**: 탭, 편집기 상태, 미리보기 업데이트, 가져오기, 내보내기, 공유, UI 동작. -3. **`styles.css`**: 레이아웃, 테마, 미리보기 스타일, 인쇄 스타일. -4. **`preview-worker.js`**: Markdown 파싱과 구문 강조. -5. **`sw.js`**: 오프라인 가능 자산 캐싱. +구현된 동작과 제한은 [기능 참고(영어)](../wiki/Features.md)를 확인하세요. ---- +## 빠른 시작 -## 시작하기와 설치 +[호스팅 웹 앱](https://markdownviewer.pages.dev/)을 사용하거나 로컬 HTTP 서버로 저장소를 실행합니다. -### 💻 방법 1: 빠른 로컬 실행(설치 없음) - -`index.html`을 `file://`로 직접 여는 대신 로컬 HTTP 서버를 통해 실행하세요. - -1. 저장소를 클론하거나 다운로드합니다. -2. 저장소 폴더에서 터미널을 엽니다. -3. `python -m http.server 8080` 또는 `npx serve . -p 8080`을 실행합니다. -4. 브라우저에서 **[http://localhost:8080](http://localhost:8080)**을 엽니다. - ---- - -### 🐳 방법 2: Docker 컨테이너 - -컨테이너에서 앱을 실행합니다. - -**미리 빌드된 Docker 이미지(GHCR):** -```bash -docker run -d \ - --name markdown-viewer \ - -p 8080:80 \ - --restart unless-stopped \ - ghcr.io/thisis-developer/markdown-viewer:latest -``` - -브라우저에서 **[http://localhost:8080](http://localhost:8080)**을 엽니다. - -**로컬 Docker Compose 빌드:** ```bash git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git cd Markdown-Viewer -docker compose up -d -``` -브라우저에서 **[http://localhost:8080](http://localhost:8080)**을 엽니다. - ---- - -### 🖥️ 방법 3: 데스크톱 앱 빌드 - -소스에서 Neutralinojs 데스크톱 앱을 빌드합니다. - -1. 저장소를 클론하고 `desktop-app/` 디렉터리로 이동합니다. - ```bash - cd desktop-app - ``` -2. 의존성을 설치하고 빌드합니다. - ```powershell - npm install - npm run build - ``` - -`npm run build`는 필요한 Neutralino 바이너리를 다운로드하고 로컬 리소스를 준비한 뒤, 자체 실행 가능한 플랫폼별 실행 파일 7개를 만듭니다. - -미리 빌드된 바이너리는 [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)에서 받을 수 있습니다. - ---- - -## 사용 가이드와 키보드 단축키 - -작업 흐름, 편집기 컨트롤, 내보내기, 공유, 단축키는 [사용 가이드](../wiki/Usage-Guide.md#workspace-layout-for-editing-and-previewing-markdown)를 참고하세요. - ---- - -## 프로젝트 디렉터리 구조 - -```text -Markdown-Viewer/ -+-- index.html # 웹 앱 기본 화면 -+-- script.js # 앱 로직과 UI 제어 -+-- styles.css # 앱 및 미리보기 스타일 -+-- preview-worker.js # Markdown 미리보기 Worker -+-- sw.js # Service Worker 캐시 -+-- assets/ # 앱 이미지와 아이콘 -| +-- i18n/ # UI 번역 카탈로그와 생성기 -+-- functions/ # Cloudflare Pages Functions -+-- workers/ # Live Share Worker 소스 -+-- desktop-app/ # Neutralinojs 데스크톱 빌드 -+-- locales/ # 현지화된 README -+-- wiki/ # 프로젝트 문서 -+-- Dockerfile # Docker 이미지 설정 -+-- docker-compose.yml # 로컬 컨테이너 설정 -+-- wrangler.toml # Cloudflare 배포 설정 -+-- README.md # 프로젝트 개요 -+-- CHANGELOG.md # 릴리스 기록 -+-- LICENSE # Apache License 2.0 +python -m http.server 8080 ``` ---- +`http://localhost:8080`을 여세요. `file://`에서는 브라우저 보안 정책이 Web Worker와 Service Worker를 차단할 수 있습니다. -## Built With (기술 스택) +| 실행 대상 | 자세한 문서(영어) | +| :--- | :--- | +| PWA/정적 웹 호스팅 | [설치](../wiki/Installation.md) | +| Docker | [Docker 배포](../wiki/Docker-Deployment.md) | +| Cloudflare Pages/KV/Durable Objects | [설정](../wiki/Configuration.md) | +| Neutralino 데스크톱 애플리케이션 | [데스크톱 애플리케이션](../wiki/Desktop-App.md) | -

- HTML5 - CSS3 - JavaScript - Bootstrap - NeutralinoJS -

+## 로컬 처리와 네트워크 처리 + +Markdown Viewer는 로컬 우선 애플리케이션이지만 모든 기능이 오프라인으로 작동하는 것은 아닙니다. + +| 작업 | 기본 데이터 경로 | +| :--- | :--- | +| 편집, 로컬 가져오기, 미리보기, 작업공간 자동 저장, 대부분의 내보내기 | 기기 | +| 웹 라이브러리 및 캐시되지 않은 렌더러 의존성 | 웹/PWA 빌드에서 CDN 요청 | +| GitHub 가져오기 및 이모지 조회 | GitHub API/원시 콘텐츠 호스트 | +| PlantUML, D2, Graphviz, Vega-Lite, WaveDrom, 일부 다이어그램 미리보기 | 다이어그램 소스가 PlantUML, Kroki 또는 mermaid.ink로 전송될 수 있음 | +| 동의 후 삽입하는 이미지, GIF, 동영상 | 공개 링크 방식의 Cloudflare 임시 미디어 저장소(90일) | +| 큰 Share Snapshot | Cloudflare KV(90일) | +| Live Share | Cloudflare Durable Object WebSocket 릴레이 | +| 외부 이미지, 미디어, 링크, 지도 타일 | 문서에서 지정한 외부 호스트 | -핵심 기술 스택: HTML, CSS, JavaScript, Bootstrap, Bootstrap Icons, Neutralinojs, Marked.js, Highlight.js, DOMPurify, MathJax, Mermaid, Leaflet, Three.js, ABCJS, Markmap, Yjs, jsPDF, html2canvas, Cloudflare Pages/Workers. +Share Snapshot 및 Live Share URL은 베어러 링크입니다. 유효한 링크를 가진 사람은 링크에 포함된 권한을 사용할 수 있습니다. Live Share는 종단 간 암호화를 제공하지 않습니다. 민감한 문서에 네트워크 기능을 사용하기 전에 [개인정보 및 보안(영어)](../wiki/Privacy-and-Security.md)을 확인하세요. -의존성 로딩 방식, CDN 사용, 데스크톱 로컬 라이브러리 복사본은 [클라이언트 라이브러리 설명](../wiki/Configuration.md#client-libraries)을 참고하세요. +## 미디어 저장 방식 -일부 고급 다이어그램 엔진은 필요할 때 PlantUML, Kroki, mermaid.ink 같은 원격 렌더러를 사용합니다. 렌더러 동작과 개인정보 세부 사항은 [다이어그램 렌더러 설명](../wiki/Features.md#insert-diagrams-charts-maps-models-and-music)을 참고하세요. +- AVIF, BMP, GIF(애니메이션 GIF 포함), JPEG, PNG, WebP, MP4, WebM, Ogg를 삽입할 수 있습니다. +- 처음 동의한 후 미디어는 Cloudflare 임시 저장소에 업로드되고 짧은 콘텐츠 주소형 HTTPS URL로 삽입됩니다. +- URL을 아는 사람은 만료 전까지 미디어를 가져올 수 있습니다. +- 같은 콘텐츠를 마지막으로 업로드한 시점부터 90일 후 만료됩니다. +- Share Snapshot과 Live Share는 Markdown 안의 URL을 공유할 뿐 별도의 미디어 복사본을 만들지 않습니다. ---- +## 주요 제한 -## 개인정보 +- 작업공간에는 최대 50개 문서를 둘 수 있습니다. 잠긴 Secret Workspace 수와 임시 Share Snapshot/Live Share 탭도 포함됩니다. +- 로컬 Markdown 파일 하나의 최대 크기는 10 MB입니다. +- GitHub 가져오기는 저장소/폴더 결과에서 Markdown 파일을 최대 30개까지 표시합니다. +- 처리 전 미디어 원본은 25 MiB까지입니다. 저장 한도는 정지 이미지 300 KiB, GIF 5 MiB, 동영상 10 MiB입니다. +- 저장형 Share Snapshot은 최대 8,000,000자이며 90일 후 만료됩니다. +- Live Share는 WebSocket 참가자 최대 64명, 실시간 메시지당 8 MB까지 지원합니다. +- STL은 소스 2 MiB, 렌더링 지오메트리 300,000개 정점으로 제한됩니다. +- 래스터 PDF/PNG는 브라우저 메모리, Canvas, CORS 제한의 영향을 받습니다. -Markdown Viewer는 클라우드 작업 공간이 아닙니다. 일반 입력, 미리보기 렌더링, 로컬 파일 가져오기, 탭 자동 저장, 테마 설정, 대부분의 내보내기는 사용자의 기기에서 처리됩니다. 로그인은 필요하지 않으며 분석, 텔레메트리, 광고, 추적 쿠키를 구현하지 않습니다. +## 개인정보 관련 중요 사항 -네트워크 사용은 동의한 관리형 미디어 업로드, GitHub 가져오기, 원격 다이어그램 렌더러, Share Snapshot, Live Share, CDN 라이브러리, 외부 문서 자산처럼 사용자가 실행하는 기능에 한정됩니다. 작업 공간 설정의 Private mode를 사용하면 편집 및 리뷰 도구는 그대로 사용하면서 문서 내용, 작업 공간 상태, 리뷰 피드백을 현재 세션에만 유지할 수 있습니다. 전체 내용은 [데이터 처리 요약](../wiki/Features.md#data-handling-summary)을 참고하세요. +- 일반 작업공간 데이터는 브라우저 프로필 또는 데스크톱 로컬 저장소에 보관됩니다. +- 프라이빗 모드를 켜면 Secret Workspace의 암호화된 데이터까지 포함해 영구 저장된 문서 상태가 삭제되고 이후 저장이 중지됩니다. +- **작업공간 재설정**은 일반 문서, 리뷰 데이터, Secret Workspace 데이터를 삭제합니다. Markdown Viewer에서 복구할 수 없습니다. +- Live Share는 Markdown/리뷰 콘텐츠를 서버에 영구 저장하지 않습니다. 다만 역할별 베어러 권한 값과 생성 시각은 Durable Object 저장소에 보관되며, 애플리케이션 수준의 만료 시간이나 삭제 경로가 없습니다. +- Share Snapshot 생성 API는 삭제 토큰을 반환하지만 현재 UI는 해당 토큰을 표시하거나 만료 전 삭제 작업을 제공하지 않습니다. +- 애플리케이션 코드에는 계정, 분석, 원격 측정, 광고, 추적 픽셀 또는 앱 전용 쿠키가 구현되어 있지 않습니다. 외부 서비스나 호스팅 제공자는 일반 요청 로그를 처리할 수 있습니다. -## 보안 및 개인정보 보호 +> **경고:** 프라이빗 모드 또는 **작업공간 재설정**을 사용하기 전에 필요한 문서를 Markdown으로 내보내세요. -- 미리보기 HTML은 삽입 전에 정리됩니다. 내보낸 HTML에는 제한적인 CSP와 외부 자산용 SRI 메타데이터가 포함됩니다. -- Secret Workspace는 PBKDF2-SHA-256으로 비밀번호에서 로컬 키를 만들고 AES-GCM으로 파일 및 폴더 이름을 암호화합니다. 키는 잠금 해제된 세션 동안만 유지되며, 잊어버린 비밀번호는 복구할 수 없습니다. -- Cloudflare Pages는 `_headers`를 사용해 CSP, 클릭재킹 방지, 리퍼러 및 권한 정책, MIME 스니핑 방지를 적용합니다. 민감한 경로는 404로 리디렉션됩니다. -- 관리형 미디어 및 저장형 Share Snapshot API 업로드는 프로덕션 앱, 미리보기, `null`, 로컬 개발 출처로 제한됩니다. 이미지, GIF, 동영상은 추측하기 어려운 공개 링크로 90일간 가져올 수 있습니다. 스냅샷 응답은 `no-store`를 사용하며 생성자는 삭제 토큰을 받습니다. -- STL 렌더링은 WebGL 처리 전에 크기가 너무 큰 소스, 유한하지 않은 형상, 과도한 정점 수를 거부합니다. -- Neutralino 데스크톱 빌드는 기본 `os.execCommand`를 노출하지 않고 네이티브 API를 명시적인 허용 목록으로 제한합니다. 자세한 내용은 [보안 모델](../wiki/Features.md#security-model)과 [설정 참고](../wiki/Configuration.md#share-api)를 확인하세요. +## 문서 ---- +상세 페이지는 영어로 유지 관리됩니다. -## 기여와 코드 품질 +| 목적 | 페이지(영어) | +| :--- | :--- | +| 전체 기능과 제한 | [Features](../wiki/Features.md) | +| 일상 사용법과 단축키 | [Usage Guide](../wiki/Usage-Guide.md) | +| Markdown/다이어그램 구문 | [Markdown Reference](../wiki/Markdown-Reference.md) | +| Share Snapshot | [Share Snapshot](../wiki/Share-Snapshot.md) | +| Live Share | [Live Share](../wiki/Live-Share-Cloudflare.md) | +| 개인정보 및 보안 | [Privacy and Security](../wiki/Privacy-and-Security.md) | +| 설치 및 배포 | [Installation](../wiki/Installation.md) | +| 문제 해결 | [Troubleshooting](../wiki/Troubleshooting.md)/[FAQ](../wiki/FAQ.md) | +| 기여 | [Contributing](../wiki/Contributing.md) | +| 다국어 용어 및 현지화 | [Localization and Terminology](../wiki/Localization.md) | -커뮤니티 기여를 환영합니다! Pull Request를 만들기 전에 [코드 변경 전 기여 안내](../wiki/Contributing.md#before-changing-code)를 확인하세요. +## 쇼케이스 프로젝트 -### 핵심 워크플로 요약: -1. **Fork** 저장소를 포크하고 기능 브랜치를 만듭니다(`git checkout -b feature/your-feature`). -2. **코드 스타일 확인:** HTML, CSS, JS 파일 전체에서 깔끔한 2칸 들여쓰기를 유지하세요. 원시 HTML 구조는 의미론적으로 작성하세요. 처리 Worker 안에서 직접 DOM 쿼리를 사용하는 것은 피하세요. -3. **Conventional Commits:** `feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `perf:`, `chore:` 접두사가 붙은 명확한 커밋 메시지를 작성하세요. -4. **테스트:** Chrome, Firefox, Edge, Safari 뷰포트에서 변경 사항을 테스트하세요. +Markdown Viewer를 활용한 다음 커뮤니티 프로젝트는 해당 개발자가 독립적으로 유지 관리합니다. ---- +- [**Markdown Desk**](https://github.com/jhrepo/markdown-desk): Tauri로 만든 네이티브 macOS 래퍼입니다. 네이티브 파일 대화 상자와 파일 핸들러, 메뉴 막대 통합, 자동 다시 불러오기 및 앱 내 업데이트 기능을 추가합니다. -## 쇼케이스와 커뮤니티 프로젝트 +## 개발 여정 -* **[Markdown Desk](https://github.com/jhrepo/markdown-desk):** Tauri로 만든 네이티브 macOS 래퍼로, 네이티브 파일 시스템 핸들러, 메뉴 막대 통합, 자동 다시 로드 기능을 추가합니다. +Markdown Viewer는 PC에서 시작한 작은 개인 프로젝트였습니다. 호기심에서 출발해 실수와 수정을 거치고 많은 정성을 담아 만든 단순한 Markdown 뷰어입니다. 초기 버전은 지금도 온라인에서 사용할 수 있으며 프로젝트의 중심으로 남아 있습니다. ---- +더 자세한 역사는 [Development Journey(영어)](../wiki/Development-Journey.md)를 참조하세요. ## 기여자 -Markdown Viewer에 기여해 주신 모든 분께 감사드립니다. +Markdown Viewer는 커뮤니티의 기여를 통해 성장하고 있습니다. - Contributors + Markdown Viewer 기여자 ---- - -## 📈 개발 여정 - -Markdown Viewer는 PC에서 시작한 작은 개인 프로젝트였습니다. 호기심, 실수, 수정, 많은 정성으로 만들어진 간단한 Markdown 뷰어였습니다. 원래 버전은 아직 온라인에 있으며, 여전히 이 프로젝트의 중심에 남아 있습니다. - -현재의 Markdown Viewer는 커뮤니티 피드백, Issue, PR, 스크린샷, GIF, 제안, 실제 문서 작업 흐름을 통해 성장했습니다. 기술적인 발전도 중요하지만, 이 여정에는 감정적인 면도 있습니다. 많은 사람들이 이 앱이 오늘의 모습이 되도록 함께 만들어 주었습니다. - ---- - -## 라이선스 - -이 프로젝트는 Apache License 2.0으로 제공됩니다. 전체 약관과 조건은 [LICENSE](../LICENSE)를 참고하세요. - ---- - -## 연락처와 지원 +## 기여 및 라이선스 -개발 및 유지 관리: **[ThisIs-Developer](https://github.com/ThisIs-Developer)** +Pull Request를 만들기 전에 [Contributing(영어)](../wiki/Contributing.md)을 읽어 주세요. 재현 가능한 버그와 구체적인 기능 제안은 [이슈 추적기](https://github.com/ThisIs-Developer/Markdown-Viewer/issues)에 등록할 수 있습니다. 취약점 세부 정보는 일반 이슈에 게시하지 마세요. -* **버그 보고와 요청:** [Issue 제출](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) -* **문서:** [Wiki 시작 안내](../wiki/Home.md#start-here) +Markdown Viewer는 [Apache License 2.0](../LICENSE)에 따라 제공됩니다. diff --git a/locales/README_tw.md b/locales/README_tw.md new file mode 100644 index 00000000..ea391b0c --- /dev/null +++ b/locales/README_tw.md @@ -0,0 +1,189 @@ +
+ + Markdown Viewer 標誌 + +

Markdown Viewer

+ + **提供即時預覽的本機優先 Markdown 編輯器與檢視器** + + 在瀏覽器、漸進式 Web 應用程式(PWA)、Docker 或 Neutralino 桌面應用程式中開啟、撰寫、整理、審閱、轉譯及匯出 Markdown;需要時也能使用分享與協作功能。 + + [![授權條款](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](../LICENSE) + [![最新版本](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + +

+ + 在 CodeWiki 上探索 Markdown Viewer + + + 在 DeepWiki 上探索 Markdown Viewer + +

+ + [English](../README.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [简体中文](README_zh.md) · **繁體中文** + + [開啟 Web 應用程式](https://markdownviewer.pages.dev/) · [文件(英文)](../wiki/Home.md) · [回報問題](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) · [版本發佈](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + +
+ +
+目錄(點選展開) + +- [Markdown Viewer 簡介](#markdown-viewer-簡介) +- [主要功能](#主要功能) +- [快速開始](#快速開始) +- [本機處理與網路處理](#本機處理與網路處理) +- [媒體儲存方式](#媒體儲存方式) +- [主要限制](#主要限制) +- [重要隱私權說明](#重要隱私權說明) +- [文件](#文件) +- [展示專案](#展示專案) +- [開發歷程](#開發歷程) +- [貢獻者](#貢獻者) +- [參與貢獻與授權條款](#參與貢獻與授權條款) + +
+ +## Markdown Viewer 簡介 + +Markdown Viewer 是一個開放原始碼、本機優先的工作區,適合開發人員、寫作者、學生、研究人員及所有使用 `.md` 或 `.markdown` 檔案的使用者。它不僅是純文字工具:在一個專注的工作區中整理多份文件,在不變更 Markdown 的情況下透過留言與建議進行審閱,並轉譯圖表、地圖、資料圖、數學公式、3D 模型及音樂。 + +將文件轉換為 Share Snapshot 連結以便快速分享,或啟動具備存取控制的 Live Share,進行即時共同編輯並使用即時游標、留言與建議。日常編輯在裝置上完成。無需帳號,應用程式也不包含廣告、分析、遙測或訂閱。 + +

+ Markdown Viewer 應用程式介面 +

+ +## 主要功能 + +- **工作區與文件:** 在巢狀資料夾中整理最多 50 份文件,並使用最近使用、我的最愛、搜尋、分頁、批次操作及加密的 Secret Workspace(秘密工作區)。 +- **編輯與審閱:** 在編輯器、分割檢視與預覽之間切換,並使用格式工具、自訂復原/重做、尋找與取代、LTR/RTL、留言與建議。 +- **Markdown 轉譯:** 支援 CommonMark 風格基礎語法、GitHub-Flavored Markdown(GFM)、表格、工作清單、提示區塊、註腳、定義清單、程式碼語法醒目提示、已清理的 HTML 與 MathJax。 +- **視覺內容:** 轉譯 Mermaid、PlantUML、Graphviz/DOT、D2、Vega-Lite、WaveDrom、Markmap、GeoJSON、TopoJSON、STL 與 ABC 記譜。 + +

+ 圖表插入模組 + 圖表轉譯範例 + 3D STL 檢視 + 全螢幕 3D STL 檢視 +

+ +- **導入與匯出:** 開啟本機檔案或公開 GitHub 內容,並匯出 Markdown、獨立 HTML、PNG、瀏覽器列印/另存為 PDF 或舊版點陣 PDF。 +- **選用分享功能:** 建立「僅供查看」或「可以編輯」模式的 Share Snapshot(分享快照),或啟動具有主持人、可以編輯與僅供查看權限的暫時 Live Share(即時共享)房間。 + +

+ Live Share 工作階段 +

+ +- **多種執行方式:** 使用託管 Web 應用程式、PWA、靜態託管、Docker、Cloudflare 或 Neutralino 桌面應用程式。 + +如需瞭解已實作的行為與限制,請參閱[功能參考(英文)](../wiki/Features.md)。 + +## 快速開始 + +直接使用[託管 Web 應用程式](https://markdownviewer.pages.dev/),或透過本機 HTTP 伺服器執行儲存庫: + +```bash +git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git +cd Markdown-Viewer +python -m http.server 8080 +``` + +開啟 `http://localhost:8080`。請勿依賴 `file://`;瀏覽器安全規則可能會封鎖 Web Worker 與 Service Worker。 + +| 執行目標 | 詳細文件(英文) | +| :--- | :--- | +| PWA/靜態 Web 託管 | [安裝](../wiki/Installation.md) | +| Docker | [Docker 部署](../wiki/Docker-Deployment.md) | +| Cloudflare Pages/KV/Durable Objects | [設定](../wiki/Configuration.md) | +| Neutralino 桌面應用程式 | [桌面應用程式](../wiki/Desktop-App.md) | + +## 本機處理與網路處理 + +Markdown Viewer 以本機處理為優先,但並非所有功能都能離線執行。 + +| 操作 | 預設資料路徑 | +| :--- | :--- | +| 編輯、本機導入、預覽、工作區自動儲存及大多數匯出 | 裝置本機 | +| Web 程式庫與未快取的轉譯器相依項目 | Web/PWA 版本向 CDN 發出要求 | +| GitHub 導入與表情符號查詢 | GitHub API/原始內容主機 | +| PlantUML、D2、Graphviz、Vega-Lite、WaveDrom 與部分圖表預覽 | 圖表原始碼可能傳送至 PlantUML、Kroki 或 mermaid.ink | +| 經同意後插入的圖片、GIF 與影片 | 透過公開連結存取的 Cloudflare 暫存媒體儲存空間(90 天) | +| 大型 Share Snapshot | Cloudflare KV(90 天) | +| Live Share | Cloudflare Durable Object WebSocket 轉送 | +| 外部圖片、媒體、連結與地圖圖磚 | 文件指定的外部主機 | + +Share Snapshot 與 Live Share URL 都是持有者連結。任何取得有效連結的人都能使用連結內含的權限。Live Share 不提供端對端加密。在對敏感文件使用網路功能前,請先閱讀[隱私權與安全性(英文)](../wiki/Privacy-and-Security.md)。 + +## 媒體儲存方式 + +- 可插入 AVIF、BMP、GIF(包括動畫 GIF)、JPEG、PNG、WebP、MP4、WebM 與 Ogg。 +- 首次同意後,媒體會上傳至 Cloudflare 暫存空間,並以短的內容定址 HTTPS URL 插入。 +- 任何取得 URL 的人都能在連結到期前擷取媒體。 +- 連結會在相同內容最近一次上傳的 90 天後到期。 +- Share Snapshot 與 Live Share 只會分享 Markdown 中的 URL,不會建立另一份媒體副本。 + +## 主要限制 + +- 工作區最多可包含 50 份文件,其中包括已鎖定 Secret Workspace 的計數及暫時 Share Snapshot/Live Share 分頁。 +- 單一本機 Markdown 檔案的大小上限為 10 MB。 +- GitHub 導入器在每個儲存庫/資料夾結果中最多顯示 30 個 Markdown 檔案。 +- 處理前的媒體來源檔案上限為 25 MiB;儲存上限為靜態圖片 300 KiB、GIF 5 MiB、影片 10 MiB。 +- 儲存型 Share Snapshot 最多包含 8,000,000 個字元,並在 90 天後到期。 +- Live Share 最多允許 64 位 WebSocket 參與者,單一即時訊息上限為 8 MB。 +- STL 原始碼上限為 2 MiB,轉譯後幾何最多為 300,000 個頂點。 +- 點陣 PDF/PNG 匯出受瀏覽器記憶體、Canvas 與 CORS 限制。 + +## 重要隱私權說明 + +- 一般工作區資料會儲存在瀏覽器設定檔或桌面本機儲存空間。 +- 啟用隱私模式會清除已持久儲存的文件狀態(包括 Secret Workspace 的加密資料),並停止後續持久儲存。 +- **重設工作區**會刪除一般文件、審閱資料與 Secret Workspace 資料;Markdown Viewer 無法復原這些內容。 +- Live Share 不會在伺服器端持久儲存 Markdown/審閱內容,但會將各角色的持有者權限值與建立時間寫入 Durable Object 儲存空間;目前未實作應用程式層級的到期時間或刪除路徑。 +- Share Snapshot 建立 API 會傳回刪除權杖,但目前的介面不會顯示該權杖,也不提供提前刪除操作。 +- 應用程式程式碼未實作帳號、分析、遙測、廣告、追蹤像素或應用程式專用 Cookie。外部服務與託管提供者仍可能處理一般要求記錄。 + +> **警告:** 啟用隱私模式或選取**重設工作區**前,請先將需要保留的文件匯出為 Markdown。 + +## 文件 + +詳細頁面以英文維護。 + +| 目的 | 頁面(英文) | +| :--- | :--- | +| 完整功能與限制 | [Features](../wiki/Features.md) | +| 日常操作與快速鍵 | [Usage Guide](../wiki/Usage-Guide.md) | +| Markdown/圖表語法 | [Markdown Reference](../wiki/Markdown-Reference.md) | +| Share Snapshot | [Share Snapshot](../wiki/Share-Snapshot.md) | +| Live Share | [Live Share](../wiki/Live-Share-Cloudflare.md) | +| 隱私權與安全性 | [Privacy and Security](../wiki/Privacy-and-Security.md) | +| 安裝與部署 | [Installation](../wiki/Installation.md) | +| 疑難排解 | [Troubleshooting](../wiki/Troubleshooting.md)/[FAQ](../wiki/FAQ.md) | +| 參與貢獻 | [Contributing](../wiki/Contributing.md) | +| 多語言術語與在地化 | [Localization and Terminology](../wiki/Localization.md) | + +## 展示專案 + +以下以 Markdown Viewer 為基礎的社群專案由其開發者獨立維護。 + +- [**Markdown Desk**](https://github.com/jhrepo/markdown-desk):使用 Tauri 建置的原生 macOS 封裝應用程式,新增原生檔案對話方塊與檔案處理常式、選單列整合、自動重新載入及應用程式內更新功能。 + +## 開發歷程 + +Markdown Viewer 最初是 PC 上的一個小型個人專案:一款源自好奇心、歷經錯誤與修正,並投入許多心力的簡單 Markdown 檢視器。初始版本目前仍可在線上存取,也始終是這個專案的初心所在。 + +若要瞭解更完整的專案歷史,請閱讀 [Development Journey(英文)](../wiki/Development-Journey.md)。 + +## 貢獻者 + +Markdown Viewer 在社群貢獻者的共同參與下持續成長。 + + + Markdown Viewer 貢獻者 + + +## 參與貢獻與授權條款 + +建立 Pull Request 前,請先閱讀 [Contributing(英文)](../wiki/Contributing.md)。可重現的錯誤與明確的功能建議可提交至 [Issue Tracker](https://github.com/ThisIs-Developer/Markdown-Viewer/issues)。請勿在一般 Issue 中公開弱點細節。 + +Markdown Viewer 採用 [Apache License 2.0](../LICENSE)。 diff --git a/locales/README_zh.md b/locales/README_zh.md index dfdebd99..e9ea4da8 100644 --- a/locales/README_zh.md +++ b/locales/README_zh.md @@ -1,340 +1,189 @@
- Markdown Viewer Logo + Markdown Viewer 徽标 -

Markdown Viewer - 在线 Markdown 编辑器与实时预览

+

Markdown Viewer

- **一款基于浏览器的 Markdown 编辑器、查看器、预览器和阅读器。** + **提供实时预览的本地优先 Markdown 编辑器与查看器** - *打开、阅读、编辑和预览 `.md` 文件,支持分屏实时 Markdown 预览、同步滚动、GitHub-Flavored Markdown、图表、地图、3D STL 预览、ABC 记谱播放、PDF/HTML/PNG 导出,以及 Web、桌面和 Docker 上的多标签文档工作区。* + 在浏览器、渐进式 Web 应用(PWA)、Docker 或 Neutralino 桌面应用中打开、编写、整理、审阅、渲染和导出 Markdown;需要时还可使用分享与协作功能。 - [![License](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](https://github.com/ThisIs-Developer/Markdown-Viewer/blob/main/LICENSE) - [![Latest Release](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) - [![Last Commit](https://img.shields.io/github/last-commit/ThisIs-Developer/Markdown-Viewer?style=flat-square)](https://github.com/ThisIs-Developer/Markdown-Viewer/commits/main) - [![Stars](https://img.shields.io/github/stars/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=dfb317)](https://github.com/ThisIs-Developer/Markdown-Viewer/stargazers) + [![许可证](https://img.shields.io/github/license/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=red)](../LICENSE) + [![最新版本](https://img.shields.io/github/v/release/ThisIs-Developer/Markdown-Viewer?style=flat-square&color=FF6B00)](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)

- CodeWiki + 在 CodeWiki 上探索 Markdown Viewer - DeepWiki + 在 DeepWiki 上探索 Markdown Viewer

- 🌐 [English](../README.md) • **简体中文** • [日本語](README_ja.md) • [한국어](README_ko.md) • 更多语言 + [English](../README.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · **简体中文** · [繁體中文](README_tw.md) - [在线演示](https://markdownviewer.pages.dev/) • [Wiki](../wiki/Home.md#start-here) • [问题反馈](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) • [版本发布](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) + [打开 Web 应用](https://markdownviewer.pages.dev/) · [文档(英文)](../wiki/Home.md) · [报告问题](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) · [版本发布](https://github.com/ThisIs-Developer/Markdown-Viewer/releases)
-## 目录 -
- 📂 目录(点击展开) -
- - - [项目简介](#项目简介) - - [快速试用](#快速试用) - - [核心功能](#核心功能) - - [Markdown 编辑与实时预览](#markdown-编辑与实时预览) - - [图表与可视化内容](#图表与可视化内容) - - [分享、协作与导出](#分享协作与导出) - - [系统架构](#系统架构) - - [核心文件说明](#核心文件说明) - - [开始使用与安装](#开始使用与安装) - - [使用指南与快捷键](#使用指南与快捷键) - - [项目目录结构](#项目目录结构) - - [Built With(技术栈)](#built-with技术栈) - - [隐私](#隐私) - - [安全与隐私控制](#安全与隐私控制) - - [贡献与代码质量](#贡献与代码质量) - - [展示与社区项目](#展示与社区项目) - - [贡献者](#贡献者) - - [📈 开发历程](#-开发历程) - - [许可证](#许可证) - - [联系与支持](#联系与支持) -
+目录(点击展开) + +- [Markdown Viewer 简介](#markdown-viewer-简介) +- [核心功能](#核心功能) +- [快速开始](#快速开始) +- [本地处理与网络处理](#本地处理与网络处理) +- [媒体存储方式](#媒体存储方式) +- [主要限制](#主要限制) +- [重要隐私说明](#重要隐私说明) +- [文档](#文档) +- [展示项目](#展示项目) +- [开发历程](#开发历程) +- [贡献者](#贡献者) +- [参与贡献与许可证](#参与贡献与许可证) ---- + -## 项目简介 +## Markdown Viewer 简介 -**Markdown Viewer** 是一款开源、基于浏览器的 Markdown 编辑器和查看器,适用于 `.md` 和 `.markdown` 文件。它将纯文本 Markdown 编辑、GitHub 风格实时预览、多文档标签、图表即代码、数学公式、导出、分享,以及 Web/桌面部署选项组合在一起。 +Markdown Viewer 是一个开源、本地优先的工作区,适合开发者、写作者、学生、研究人员以及所有使用 `.md` 或 `.markdown` 文件的用户。它不止于纯文本:在一个专注的工作区中整理多个文档,在不改动 Markdown 的情况下通过评论和建议进行审阅,并渲染图表、地图、数据图、数学公式、3D 模型和音乐。 -大多数编辑、预览、自动保存、本地文件导入、设置和导出都在你的设备上完成。需要网络的功能会明确说明。无需登录即可使用。 +将文档转换为 Share Snapshot 链接以便快速分享,或启动带访问控制的 Live Share,进行实时协同编辑并使用实时光标、评论和建议。日常编辑在设备上完成。无需账号,应用也不包含广告、分析、遥测或订阅。

- Markdown Viewer - 支持 GFM 渲染、多文档标签工作区和深色主题的分屏实时 Markdown 编辑器与预览器 + Markdown Viewer 应用界面

-## 快速试用 - -1. 打开 [在线 Markdown 编辑器](https://markdownviewer.pages.dev/)。 -2. 拖入 `.md` 或 `.markdown` 文件,或直接开始编写。 -3. 根据需要使用实时预览、**Insert Diagram & More**、导出菜单、Share Snapshot 或 Live Share。 - -更多说明请查看 Wiki 中的 [功能](../wiki/Features.md#product-summary)、[隐私](../wiki/Home.md#privacy-at-a-glance)、[分享](../wiki/Features.md#share-markdown-with-snapshot-links)、[导出](../wiki/Features.md#export-markdown-to-pdf-html-png-and-md) 和 [桌面版](../wiki/Features.md#desktop-app) 部分。 - ## 核心功能 -Markdown Viewer 覆盖常见 Markdown 基础能力,同时帮助用户在不离开编辑器的情况下创建更丰富的技术文档。 - -1. **GitHub-Flavored Markdown (GFM)**:编写普通 Markdown,并支持表格、任务列表、删除线、自动链接、代码块、提示块、脚注和实时预览。大多数 Markdown 编辑器都覆盖基础功能;下面的功能展示了 Markdown Viewer 为更丰富的技术文档额外提供的能力。 -2. **Advanced Diagram Support & More**:一个 **Insert Diagram & More** 按钮会打开可视化模板、预览和可直接插入的示例,让用户无需记住每种语法也能添加复杂内容。 - - - **Mermaid**:创建流程图、时序图、甘特图、状态图和适合文档的架构可视化。 - - **PlantUML**:为软件设计笔记添加时序图、类图、用例图和工程图。 - - **Graphviz**:渲染用于树、依赖关系图和网络关系的 DOT 图。 - - **D2**:使用现代布局输出构建清晰的图表即代码。 - - **Vega-Lite**:直接在 Markdown 中描述图表和数据可视化。 - - **Markmap**:将嵌套 Markdown 列表转换为适合规划和学习笔记的思维导图。 - - **WaveDrom**:为硬件或协议工作记录时序图和信号波形。 - - **Map**:在不离开文档的情况下预览 GeoJSON 和 TopoJSON 数据。 - - **STL 3D Model Renderer**:在技术笔记旁预览 3D 模型。 - - **ABC Music Player & Sheet Music Viewer**:乐谱渲染和浏览器播放。 - -3. **文档资源管理器与双文档分屏**:在嵌套文件夹中整理最多 50 个已存储文件,使用批量文件操作,并在两个并排文档中完整渲染 Markdown、数学公式、图表、地图、STL 和 ABC 记谱。 -4. **Comments & Suggestions**:无需更改 Markdown 源码,即可在渲染后的文档块上添加、管理和解决反馈。 -5. **Live Share Temporary Rooms**:通过服务器验证的主持人、可编辑和仅查看权限进行实时协作,适合快速编辑、审阅或结对写作。 -6. **Share Snapshot Links**:在需要快速发送文档状态时,创建只读或可编辑的时间点快照链接。较大的已存储快照会在 90 天后过期。 -7. **LaTeX Math Notation**:使用 MathJax 渲染行内和块级公式,适合数学笔记、论文和技术说明。 -8. **Markdown to PDF, HTML & PNG Export**:导出 Markdown、HTML、PNG、浏览器打印/另存为 PDF,或 Legacy Raster PDF,适合需要分享、打印或归档的文档。 -9. **隐私与安全控制**:在工作区设置中启用隐私模式,使文档和审阅数据仅保留在当前会话中;预览会经过清理,导出的 HTML 经过安全加固,桌面原生 API 也受到限制。 - -完整细节、限制和隐私说明请查看 [功能参考](../wiki/Features.md#product-summary)。 - -## Markdown 编辑与实时预览 - -- 编写纯文本 Markdown,同时实时预览渲染 GFM、语法高亮、数学公式、提示块、脚注、表格、任务列表和已清理的 HTML。 -- 在响应式资源管理器中整理最多 50 个已存储 Markdown 文件。它包含固定的 Workspace 和 Secret Workspace 根目录、嵌套文件夹、搜索、最近使用、收藏、拖放移动、悬停展开文件夹和边缘自动滚动。Secret Workspace 内容会在设备上用密码加密。 -- 从文件菜单并排打开两个文档。一个共享控件可让两侧在编辑和预览之间切换;预览模式能渲染 Markdown、数学公式、Mermaid 和远程图表、地图、STL 模型与 ABC 记谱。可以在资源管理器中多选文件并批量打开、移动或删除,也可以右键空白区域或文档区域打开相关操作。 -- 在编辑器光标处粘贴、上传或拖入图片、动画 GIF,以及 MP4、WebM 或 Ogg 视频。进度提示会显示上传状态;托管媒体使用短的内容寻址 HTTPS 链接,可在刷新、Share Snapshot、Live Share 和 Markdown 导出后继续使用,直到 90 天后过期。首次同意后,也可以转换已有的内嵌栅格图片。 -- 使用 WYSIWYG 风格的工具栏辅助功能,同时保留对纯文本 Markdown 源码的完全控制。 -- 通过防抖渲染和后台 Worker 预览大型文档,让输入保持响应迅速。 - -## 图表与可视化内容 - -Markdown Viewer 也适合作为技术笔记、文档、硬件说明、音乐片段和数据密集型文档中的 Markdown 图表编辑器。 - -- **Mermaid、PlantUML、Graphviz / DOT 和 D2**:用于流程图、时序图、类图、架构草图、依赖关系图和图表即代码工作流。 -- **Vega-Lite 和 Markmap**:用于 Markdown 图表、数据可视化和思维导图。 -- **WaveDrom**:用于时序图和信号文档。 -- **GeoJSON 和 TopoJSON 地图**:用于带位置数据的 Markdown 文档。 -- **STL 3D 模型预览**:用于在笔记旁检查 3D 模型片段。 -- **ABC 记谱**:用于乐谱渲染和浏览器播放。 +- **工作区与文档:** 在嵌套文件夹中整理最多 50 个文档,并使用最近使用、收藏夹、搜索、标签页、批量操作和加密的 Secret Workspace(秘密工作区)。 +- **编辑与审阅:** 在编辑器、分屏视图和预览之间切换,使用格式工具、自定义撤销/重做、查找和替换、LTR/RTL、评论与建议。 +- **Markdown 渲染:** 支持 CommonMark 风格基础语法、GitHub-Flavored Markdown(GFM)、表格、任务列表、提示块、脚注、定义列表、代码语法高亮、已清理的 HTML 和 MathJax。 +- **可视化内容:** 渲染 Mermaid、PlantUML、Graphviz/DOT、D2、Vega-Lite、WaveDrom、Markmap、GeoJSON、TopoJSON、STL 和 ABC 记谱。

- 图表支持与更多功能 - ABC 音乐记谱与音频合成 - STL 3D 模型渲染器 + 图表插入模块 + 图表渲染示例 + 3D STL 视图 + 全屏 3D STL 视图

-## 分享、协作与导出 - -- **Comments & Suggestions** 在不更改 Markdown 的情况下,为渲染后的 YAML、标题、段落、代码块和图表添加审阅层。反馈可以添加、编辑、解决、重新打开、删除或复制;它保存在普通标签中,并且只在活跃的 Live Share 房间内同步。 -- **Share Snapshot** 创建用于时间点 Markdown 分享的快速链接。小文档可以保留在 URL hash 中;较大的快照会在配置该后端时使用 Cloudflare KV 临时存储最多 90 天。快照属于持有链接即可访问的链接,任何拿到链接的人都能打开。 -

- Share Snapshot -

+- **导入与导出:** 打开本地文件或公开 GitHub 内容,导出 Markdown、独立 HTML、PNG、浏览器打印/另存为 PDF 或旧版栅格 PDF。 +- **可选分享:** 创建“仅供查看”或“可以编辑”模式的 Share Snapshot(分享快照),或者启动具有主持人、可以编辑和仅供查看权限的临时 Live Share(实时共享)房间。 -- **Live Share rooms** 通过 Cloudflare Durable Objects 提供临时协作编辑,并由服务器检查主持人、可编辑和仅查看权限。它适用于审阅和结对写作,但不是端到端加密。

- Live Share rooms + Live Share 会话

-- **Markdown export** 下载原始 `.md` 文档。 -- **HTML export** 创建独立渲染文档。 -- **PDF export** 包括浏览器打印/另存为 PDF 和 Legacy Raster PDF。 -- **PNG export** 将渲染预览捕获为图片。 - ---- - -## 系统架构 - -Markdown Viewer 是一个客户端单页应用。`script.js` 控制界面,`preview-worker.js` 在后台编译 Markdown,`sw.js` 处理具备离线能力的缓存。 - -### 核心文件说明 - -1. **`index.html`**:应用布局以及脚本/样式入口。 -2. **`script.js`**:标签页、编辑器状态、预览更新、导入、导出、分享和 UI 行为。 -3. **`styles.css`**:布局、主题、预览样式和打印样式。 -4. **`preview-worker.js`**:后台 Markdown 解析和语法高亮。 -5. **`sw.js`**:具备离线能力的资源缓存。 +- **多种运行方式:** 使用托管 Web 应用、PWA、静态托管、Docker、Cloudflare 或 Neutralino 桌面应用。 ---- +有关已实现的行为和限制,请参阅[功能参考(英文)](../wiki/Features.md)。 -## 开始使用与安装 +## 快速开始 -### 💻 方式 1:快速本地运行(无需安装) - -请通过本地 HTTP 服务器运行,而不是用 `file://` 直接打开 `index.html`: - -1. 克隆或下载仓库。 -2. 在仓库目录打开终端。 -3. 运行 `python -m http.server 8080` 或 `npx serve . -p 8080`。 -4. 在浏览器中打开 **[http://localhost:8080](http://localhost:8080)**。 - ---- - -### 🐳 方式 2:Docker 容器部署 - -在容器中运行应用: - -**预构建 Docker 镜像(GHCR):** +直接使用[托管 Web 应用](https://markdownviewer.pages.dev/),或通过本地 HTTP 服务器运行仓库: -```bash -docker run -d \ - --name markdown-viewer \ - -p 8080:80 \ - --restart unless-stopped \ - ghcr.io/thisis-developer/markdown-viewer:latest -``` - -在浏览器中打开 **[http://localhost:8080](http://localhost:8080)**。 - -**本地 Docker Compose 构建:** ```bash git clone https://github.com/ThisIs-Developer/Markdown-Viewer.git cd Markdown-Viewer -docker compose up -d -``` -在浏览器中打开 **[http://localhost:8080](http://localhost:8080)**。 - ---- - -### 🖥️ 方式 3:构建桌面应用 - -从源代码构建 Neutralinojs 桌面应用: - -1. 克隆仓库并进入 `desktop-app/` 目录: - ```bash - cd desktop-app - ``` -2. 安装依赖并构建: - ```powershell - npm install - npm run build - ``` - -`npm run build` 会下载所需的 Neutralino 二进制文件、准备本地资源,并创建七个独立运行的平台可执行文件。 - -也可以从 [Releases](https://github.com/ThisIs-Developer/Markdown-Viewer/releases) 下载预构建二进制文件。 - ---- - -## 使用指南与快捷键 - -请阅读 [使用指南](../wiki/Usage-Guide.md#workspace-layout-for-editing-and-previewing-markdown),了解工作流、编辑器控制、导出、分享和快捷键。 - ---- - -## 项目目录结构 - -```text -Markdown-Viewer/ -+-- index.html # Web 应用主界面 -+-- script.js # 应用逻辑和界面控制 -+-- styles.css # 应用与预览样式 -+-- preview-worker.js # Markdown 预览 Worker -+-- sw.js # Service Worker 缓存 -+-- assets/ # 应用图片和图标 -| +-- i18n/ # 界面语言目录和生成器 -+-- functions/ # Cloudflare Pages Functions -+-- workers/ # Live Share Worker 源码 -+-- desktop-app/ # Neutralinojs 桌面版 -+-- locales/ # 本地化 README -+-- wiki/ # 项目文档 -+-- Dockerfile # Docker 镜像配置 -+-- docker-compose.yml # 本地容器配置 -+-- wrangler.toml # Cloudflare 部署配置 -+-- README.md # 项目概览 -+-- CHANGELOG.md # 版本记录 -+-- LICENSE # Apache License 2.0 +python -m http.server 8080 ``` ---- +打开 `http://localhost:8080`。不要依赖 `file://`;浏览器安全规则可能会阻止 Web Worker 和 Service Worker。 -## Built With(技术栈) +| 运行目标 | 详细文档(英文) | +| :--- | :--- | +| PWA/静态 Web 托管 | [安装](../wiki/Installation.md) | +| Docker | [Docker 部署](../wiki/Docker-Deployment.md) | +| Cloudflare Pages/KV/Durable Objects | [配置](../wiki/Configuration.md) | +| Neutralino 桌面应用 | [桌面应用](../wiki/Desktop-App.md) | -

- HTML5 - CSS3 - JavaScript - Bootstrap - NeutralinoJS -

+## 本地处理与网络处理 + +Markdown Viewer 以本地处理为优先,但并非所有功能都能离线运行。 + +| 操作 | 默认数据路径 | +| :--- | :--- | +| 编辑、本地导入、预览、工作区自动保存和大多数导出 | 设备本地 | +| Web 库与未缓存的渲染器依赖 | Web/PWA 版本向 CDN 发出请求 | +| GitHub 导入与表情符号查询 | GitHub API/原始内容主机 | +| PlantUML、D2、Graphviz、Vega-Lite、WaveDrom 和部分图表预览 | 图表源码可能发送到 PlantUML、Kroki 或 mermaid.ink | +| 经同意后插入的图片、GIF 和视频 | 通过公开链接访问的 Cloudflare 临时媒体存储(90 天) | +| 大型 Share Snapshot | Cloudflare KV(90 天) | +| Live Share | Cloudflare Durable Object WebSocket 中继 | +| 外部图片、媒体、链接和地图图块 | 文档指定的外部主机 | -核心技术栈:HTML、CSS、JavaScript、Bootstrap、Bootstrap Icons、Neutralinojs、Marked.js、Highlight.js、DOMPurify、MathJax、Mermaid、Leaflet、Three.js、ABCJS、Markmap、Yjs、jsPDF、html2canvas 和 Cloudflare Pages/Workers。 +Share Snapshot 和 Live Share URL 都是持有者链接。任何获得有效链接的人都可以使用其中包含的权限。Live Share 不提供端到端加密。在对敏感文档使用网络功能之前,请阅读[隐私与安全(英文)](../wiki/Privacy-and-Security.md)。 -依赖加载行为、CDN 使用和桌面本地库副本请查看 [客户端库说明](../wiki/Configuration.md#client-libraries)。 +## 媒体存储方式 -部分高级图表引擎会在需要时使用 PlantUML、Kroki 或 mermaid.ink 等远程渲染器。渲染器行为和隐私细节请查看 [图表渲染器说明](../wiki/Features.md#insert-diagrams-charts-maps-models-and-music)。 +- 可插入 AVIF、BMP、GIF(包括动画 GIF)、JPEG、PNG、WebP、MP4、WebM 和 Ogg。 +- 首次同意后,媒体会上传到 Cloudflare 临时存储,并以短的内容寻址 HTTPS URL 插入。 +- 任何获得 URL 的人都能在链接过期前获取媒体。 +- 链接会在相同内容最近一次上传的 90 天后过期。 +- Share Snapshot 与 Live Share 只会分享 Markdown 中的 URL,不会创建另一份媒体副本。 ---- +## 主要限制 -## 隐私 +- 工作区最多包含 50 个文档,其中包括已锁定 Secret Workspace 的计数和临时 Share Snapshot/Live Share 标签页。 +- 单个本地 Markdown 文件最大为 10 MB。 +- GitHub 导入器在每个仓库/文件夹结果中最多显示 30 个 Markdown 文件。 +- 处理前的媒体源文件最大为 25 MiB;存储上限为静态图片 300 KiB、GIF 5 MiB、视频 10 MiB。 +- 存储型 Share Snapshot 最多包含 8,000,000 个字符,并在 90 天后过期。 +- Live Share 最多允许 64 个 WebSocket 参与者,单条实时消息最大为 8 MB。 +- STL 源码最大为 2 MiB,渲染后的几何体最多为 300,000 个顶点。 +- 栅格 PDF/PNG 导出受浏览器内存、Canvas 与 CORS 限制。 -Markdown Viewer 不是云端工作区。普通输入、预览渲染、本地文件导入、标签自动保存、主题设置和大多数导出都在你的设备上进行。无需登录,应用也没有实现分析、遥测、广告或跟踪 Cookie。 +## 重要隐私说明 -网络使用只会发生在用户触发的功能中,例如经过同意的托管媒体上传、GitHub 导入、远程图表渲染器、Share Snapshot、Live Share、CDN 库和外部文档资源。工作区设置中的隐私模式会让文档内容、工作区状态和审阅反馈仅保留在当前会话中,同时仍可使用编辑和审阅工具。完整说明请查看 [数据处理摘要](../wiki/Features.md#data-handling-summary)。 +- 常规工作区数据存储在浏览器配置文件或桌面本地存储中。 +- 启用隐私模式会清除已持久化的文档状态(包括 Secret Workspace 的加密数据),并停止后续持久化。 +- **重置工作区**会删除常规文档、审阅数据和 Secret Workspace 数据;Markdown Viewer 无法恢复这些内容。 +- Live Share 不会在服务器端持久保存 Markdown/审阅内容,但会将各角色的持有者权限值和创建时间写入 Durable Object 存储;当前未实现应用级过期时间或删除路径。 +- Share Snapshot 创建 API 会返回删除令牌,但当前界面不会显示该令牌,也不提供提前删除操作。 +- 应用代码未实现账号、分析、遥测、广告、跟踪像素或应用专用 Cookie。外部服务和托管提供商仍可能处理常规请求日志。 -## 安全与隐私控制 +> **警告:** 启用隐私模式或选择**重置工作区**之前,请先将需要保留的文档导出为 Markdown。 -- 预览 HTML 在插入前会经过清理;导出的 HTML 使用严格的 CSP,并为外部资源提供 SRI 元数据。 -- Secret Workspace 使用 PBKDF2-SHA-256 从密码生成本地密钥,并用 AES-GCM 加密文件和文件夹名称。密钥只在解锁会话中保留,忘记的密码无法恢复。 -- Cloudflare Pages 通过 `_headers` 提供 CSP、防点击劫持、引用来源策略、权限策略和 MIME 类型保护;敏感路径会重定向到 404。 -- 托管媒体和已存储的 Share Snapshot API 上传仅允许生产站点、预览站点、`null` 和本地开发来源。托管图片、GIF 和视频可通过难以猜测的公开链接访问 90 天;快照响应使用 `no-store`,创建者会收到删除令牌。 -- STL 渲染会在 WebGL 处理前拒绝过大的源、非有限几何数据和过多顶点。 -- Neutralino 桌面版不开放默认的 `os.execCommand`,原生 API 仅使用明确的允许列表。详情请查看 [安全模型](../wiki/Features.md#security-model) 和 [配置参考](../wiki/Configuration.md#share-api)。 +## 文档 ---- +详细页面以英文维护。 -## 贡献与代码质量 +| 目的 | 页面(英文) | +| :--- | :--- | +| 完整功能与限制 | [Features](../wiki/Features.md) | +| 日常使用与快捷键 | [Usage Guide](../wiki/Usage-Guide.md) | +| Markdown/图表语法 | [Markdown Reference](../wiki/Markdown-Reference.md) | +| Share Snapshot | [Share Snapshot](../wiki/Share-Snapshot.md) | +| Live Share | [Live Share](../wiki/Live-Share-Cloudflare.md) | +| 隐私与安全 | [Privacy and Security](../wiki/Privacy-and-Security.md) | +| 安装与部署 | [Installation](../wiki/Installation.md) | +| 故障排除 | [Troubleshooting](../wiki/Troubleshooting.md)/[FAQ](../wiki/FAQ.md) | +| 参与贡献 | [Contributing](../wiki/Contributing.md) | +| 多语言术语与本地化 | [Localization and Terminology](../wiki/Localization.md) | -欢迎社区贡献!创建 Pull Request 前,请先查看 [修改代码前的贡献指南](../wiki/Contributing.md#before-changing-code)。 +## 展示项目 -### 核心工作流摘要: -1. **Fork** 仓库并创建功能分支(`git checkout -b feature/your-feature`)。 -2. **验证代码风格:** 在 HTML、CSS 和 JS 文件中保持干净的 2 空格缩进。确保原始 HTML 结构语义化。避免在处理 Worker 中直接查询 DOM。 -3. **Conventional Commits:** 使用带有 `feat:`、`fix:`、`docs:`、`style:`、`refactor:`、`perf:` 或 `chore:` 前缀的清晰提交消息。 -4. **测试:** 在 Chrome、Firefox、Edge 和 Safari 视口中测试你的修改。 +以下基于 Markdown Viewer 的社区项目由其开发者独立维护。 ---- +- [**Markdown Desk**](https://github.com/jhrepo/markdown-desk):使用 Tauri 构建的原生 macOS 封装应用,增加了原生文件对话框与文件处理程序、菜单栏集成、自动重新加载和应用内更新功能。 -## 展示与社区项目 +## 开发历程 -* **[Markdown Desk](https://github.com/jhrepo/markdown-desk):** 一个使用 Tauri 构建的原生 macOS 包装器,添加了原生文件系统处理、菜单栏集成和自动重新加载能力。 +Markdown Viewer 最初是 PC 上的一个小型个人项目:一款源于好奇心、经历过错误与修正,并倾注了许多心力的简单 Markdown 查看器。初始版本目前仍可在线访问,也始终是这个项目的初心所在。 ---- +如需了解更完整的项目历史,请阅读 [Development Journey(英文)](../wiki/Development-Journey.md)。 ## 贡献者 -感谢所有为 Markdown Viewer 做出贡献的人。 +Markdown Viewer 在社区贡献者的共同参与下不断成长。 - Contributors + Markdown Viewer 贡献者 ---- - -## 📈 开发历程 - -Markdown Viewer 最初是 PC 上的一个小型个人项目:一个带着好奇、错误、修复和许多用心构建出来的简单 Markdown 查看器。原始版本 仍然在线,它依然是这个项目的初心。 - -当前的 Markdown Viewer 通过社区反馈、Issue、PR、截图、GIF、建议和真实文档工作流逐渐成长。技术进步很重要,但这段旅程也有情感的一面:许多人帮助这个应用成长为今天的样子。 - ---- - -## 许可证 - -本项目基于 Apache License 2.0 授权。完整条款和条件请查看 [LICENSE](../LICENSE) 文件。 - ---- - -## 联系与支持 +## 参与贡献与许可证 -由 **[ThisIs-Developer](https://github.com/ThisIs-Developer)** 开发和维护。 +创建 Pull Request 前,请阅读 [Contributing(英文)](../wiki/Contributing.md)。可复现的缺陷和明确的功能建议可提交至 [Issue Tracker](https://github.com/ThisIs-Developer/Markdown-Viewer/issues)。请勿在普通 Issue 中发布漏洞详情。 -* **错误报告与功能请求:** [提交 Issue](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) -* **文档:** [Wiki 入门](../wiki/Home.md#start-here) +Markdown Viewer 采用 [Apache License 2.0](../LICENSE)。 diff --git a/wiki/Configuration.md b/wiki/Configuration.md index b9e5179d..3df6e7c6 100644 --- a/wiki/Configuration.md +++ b/wiki/Configuration.md @@ -16,14 +16,14 @@ This page documents the runtime, storage, dependency, Docker, Cloudflare, and de | `find-replace-docked` | `localStorage` | Find and Replace panel dock preference. | | `markdownViewerPrivateMode` | `localStorage` | Whether document-state persistence is disabled. This preference remains while document-state keys are cleared. | -The desktop app starts by copying known Neutralino storage values back into `localStorage`, then writes through `saveStorageItem()` to keep both layers aligned. +The desktop application starts by copying known Neutralino storage values back into `localStorage`, then writes through `saveStorageItem()` to keep both layers aligned. Temporary shared content is intentionally not persisted: - Share Snapshot tabs have `kind: "share-snapshot"`. - Live Share participant tabs use `kind: "live-share"` plus `temporary: true`; host documents are restored when leaving the session. -Private mode in Workspace settings clears the normal document-state keys (`markdownViewerTabs`, `markdownViewerDocumentOrganization`, `markdownViewerActiveTab`, `markdownViewerUntitledCounter`, and `markdownViewerGlobalState`) when enabled and prevents them from being written until the mode is turned off. Use **Reset workspace** in Workspace settings to remove files and review data without enabling private mode. +Private mode in Workspace settings clears the document-state keys (`markdownViewerTabs`, `markdownViewerDocumentOrganization`, `markdownViewerActiveTab`, `markdownViewerUntitledCounter`, `markdownViewerGlobalState`, and `markdownViewerSecretWorkspace`) when enabled and prevents them from being written until the mode is turned off. **Reset workspace** also removes normal files, review data, and Secret Workspace storage before recreating the welcome Document. Export needed content before either action. ## Client Libraries @@ -69,6 +69,7 @@ When running inside Neutralino, dynamic library URLs are rewritten to local `/li | Huge render debounce | 240 ms | | Minimum split pane width | 20% | | Line-height cache size | 5,000 entries | +| Local Markdown import | 10 MB per file | | GitHub importer shown files | 30 | | Share URL warning ceiling | 32,000 characters | | Legacy share URL ceiling | 4,096 characters | @@ -134,7 +135,9 @@ class_name = "LiveRoom" script_name = "markdown-viewer-live-room" ``` -`SHARE_KV` stores large Share Snapshot records and content-addressed managed media for 90 days. Re-uploading identical content refreshes that media item's 90-day expiry. The snapshot and media record types use separate key prefixes. `LIVE_ROOMS` routes Live Share WebSocket rooms to Durable Objects. Share Snapshot, managed media storage, and Live Share are separate data paths. +`SHARE_KV` stores large Share Snapshot records and content-addressed managed media for 90 days. Re-uploading identical content refreshes that media item's 90-day expiry. The snapshot and media record types use separate key prefixes. `LIVE_ROOMS` routes Live Share WebSocket rooms to Durable Objects. + +Live Share does not persist Markdown or Review content server-side. Its Durable Object does persist the host, edit, and view bearer capability values plus `createdAt` under `live-room-auth-v1`; the current implementation defines no application TTL or deletion route for that record. Share Snapshot, managed media storage, and Live Share are separate data paths. `wrangler.live-room.toml` deploys `workers/live-room-worker.js` with the `LiveRoom` Durable Object migration. @@ -147,7 +150,9 @@ script_name = "markdown-viewer-live-room" - `GET /api/share/` to load a stored snapshot. - `DELETE /api/share/` to delete a stored snapshot when the creator supplies its deletion token. -Responses set `Cache-Control: no-store` and vary CORS by request origin. The allowed origins are the production app, HTTPS `*.markdownviewer.pages.dev` previews, `null`, and localhost/127.0.0.1 development origins; unsupported origins receive `403`. Stored records contain content, mode, title, creation time, size, and a hash of the creator deletion token. The token is returned only when the snapshot is created. Invalid ids, missing content, oversized content, invalid deletion tokens, missing KV binding, and unknown routes return JSON errors. +Responses set `Cache-Control: no-store` and vary CORS by request origin. The allowed origins are the production app, HTTPS `*.markdownviewer.pages.dev` previews, `null`, and localhost/127.0.0.1 development origins; unsupported origins receive `403`. Requests without an `Origin` header are accepted, so origin filtering is not an access-control substitute. + +Stored records contain content, mode, title, creation time, size, and a hash of the creator deletion token. The token is returned only when the snapshot is created. The current UI does not display the token or expose a Delete snapshot action; API clients must capture the response to use early deletion. Invalid ids, missing content, oversized content, invalid deletion tokens, missing KV binding, and unknown routes return JSON errors. See [Share Snapshot](Share-Snapshot.md). ## Managed Media API @@ -164,9 +169,9 @@ Upload and preflight requests use the same production, Cloudflare preview, local ## Live Room API -`functions/live-room/[[room]].js` supports WebSocket upgrades only. It validates the WebSocket `Origin`, room and secret length, requires `LIVE_ROOMS`, and forwards to a Durable Object chosen by `roomName + ":" + secret`. The Durable Object authenticates host, edit, and view capabilities, filters message types by role, and enforces the participant/message limits. +`functions/live-room/[[room]].js` supports WebSocket upgrades only. It validates the WebSocket `Origin`, room and secret length, requires `LIVE_ROOMS`, and forwards to a Durable Object chosen by `roomName + ":" + secret`. The Durable Object authenticates host, edit, and view capabilities, filters message types by role, enforces the participant/message limits, and persists the capability record described above. -See [Live Share Cloudflare](Live-Share-Cloudflare) for runtime flow and limits. +See [Live Share](Live-Share-Cloudflare.md) for runtime flow and limits. ## Docker and Nginx @@ -182,7 +187,9 @@ Security headers configured in Docker/Nginx documentation include: - `Permissions-Policy` - `Cross-Origin-Opener-Policy` and `Cross-Origin-Resource-Policy` -Cloudflare Pages reads the root `_headers` and `_redirects` files. `_redirects` hides `.env`, `_headers`, and source-map paths behind 404 responses. Self-hosters should preserve equivalent policies and make sure `preview-worker.js`, `sw.js`, `manifest.json`, `script.js`, `styles.css`, `assets/`, `workers/`, and `functions/` or their Cloudflare equivalents are deployed according to the features they intend to use. +Cloudflare Pages reads the root `_headers` and `_redirects` files. `_redirects` hides `.env`, `_headers`, and source-map paths behind 404 responses. Self-hosters should preserve equivalent policies and make sure `preview-worker.js`, `sample.md`, `sw.js`, `manifest.json`, `script.js`, `styles.css`, `assets/`, `workers/`, and `functions/` or their Cloudflare equivalents are deployed according to the features they intend to use. + +The checked-in root Dockerfile does not copy `preview-worker.js` or `sample.md`; see [Docker Deployment: Known Stock Image Limitation](Docker-Deployment.md#known-stock-image-limitation). ## Neutralino Desktop Configuration @@ -234,3 +241,5 @@ The browser/chrome modes block filesystem and/or OS APIs more aggressively. Running `npm run build` first triggers `prebuild`, which runs setup and its `postsetup` preparation step. `build-standalone.js` builds each target separately to avoid exhausting Node.js memory, and every output is a self-contained executable without a neighboring `resources.neu` file. `prepare.js` copies root app files into `desktop-app/resources`, downloads and verifies libraries, rewrites dynamic library paths, strips web-only SEO metadata, and prepares local renderer/export resources for the desktop bundle. + +Related pages: [Installation](Installation.md), [Privacy and Security](Privacy-and-Security.md), [Share Snapshot](Share-Snapshot.md), [Live Share](Live-Share-Cloudflare.md), and [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Contributing.md b/wiki/Contributing.md index d7f0e924..79c7df3b 100644 --- a/wiki/Contributing.md +++ b/wiki/Contributing.md @@ -4,11 +4,13 @@ Thanks for helping improve Markdown Viewer. Contributions can include bug report ## Before Changing Code -- Read [Features](Features) to understand current user-facing behavior and privacy boundaries. +- Read [Features](Features.md) to understand current user-facing behavior and [Privacy and Security](Privacy-and-Security.md) for data boundaries. - Check `CHANGELOG.md` for historical context. - Keep changes scoped to the feature or bug you are working on. - Do not remove user-facing behavior from docs unless the code no longer implements it. +Create a branch; do not work directly on `main`. Keep documentation-only changes separate from application behavior changes when practical. + ## Local Web Development The root app has no required build step. @@ -61,13 +63,65 @@ When changing managed media, snapshot, or live behavior, update the relevant fil ## Documentation Rules -- Update existing wiki pages instead of creating new pages for small topics. +- Use concise, direct, internationally readable language and the approved feature names in [Localization and Terminology](Localization.md). +- Update the responsible Wiki page instead of creating a new page for a small addition. - Document user-facing behavior, limits, data handling, and privacy implications. - Keep wording simple and direct. - If a feature sends data to a service, say so. - If a feature is local-only, say where it is stored. - Keep README summaries aligned with the wiki. - When visible interface text changes, regenerate `assets/i18n/*.json`, review every new translation in context, and update `wiki/Localization.md` if the workflow changes. +- Verify claims against current code and tests rather than copying an older changelog statement. +- Use explicit `.md` extensions for repository-relative documentation links. + +## Translation Contributions + +1. Finalize the English source. +2. Review the terminology tables in [Localization and Terminology](Localization.md). +3. Update the relevant localized README or interface catalog without translating code, commands, paths, URLs, routes, keys, library names, Markdown syntax, or branch names. +4. Preserve Markdown structure, links, anchors, tables, and code fences. +5. Compare the translation with the English source for technical meaning and omissions. +6. Review grammar, UI-label consistency, heading length, and link targets in context. +7. Run `node assets/i18n/generate-ui-locales.mjs` only when interface catalogs are in scope, then review generated output before committing. +8. Run the desktop preparation workflow when interface catalogs change so bundled copies remain synchronized. + +Detailed Wiki pages are maintained in English. When no localized page exists, label the English destination instead of creating a broken localized link. + +## Testing + +Choose checks that match the change: + +```bash +npm run build +npm run test:e2e +``` + +`npm run build` runs the repository static asset validator. `npm run test:e2e` runs Playwright, and `npm test` runs both. Use a focused Playwright spec while iterating, then the broader applicable suite before a pull request. + +For documentation: + +- run `git diff --check`; +- validate every relative file, image, and heading anchor; +- check Markdown fences and one-H1 structure; +- compare localized README headings and navigation; +- search for outdated terminology and unsupported claims; and +- review `git diff --name-only` to confirm the intended scope. + +At commit `5511dc7`, the static validator includes a pre-existing reference to missing `functions/api/report-issue.js`. If that baseline remains, `npm run build` reports the missing asset before documentation changes. Record the baseline failure accurately; do not change product source in a documentation-only pull request. + +## Issue Reports + +Search [existing issues](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) before opening a new one. Include: + +- affected version or commit; +- browser/operating system and delivery target; +- exact reproduction steps; +- minimal non-sensitive Markdown; +- expected and actual results; +- console/network errors; and +- screenshots only when they add useful evidence. + +Do not attach confidential Documents, managed-media URLs, Share Snapshot bearer links, Live Share invitations, room secrets, capabilities, or deletion tokens. ## Commit Messages @@ -97,6 +151,8 @@ A good PR includes: Please do not open public issues for vulnerabilities. Use GitHub Security Advisories if available or contact the maintainers privately with a minimal reproduction and impact notes. +Include the affected version/commit, required preconditions, impact, minimal reproduction, and a suggested mitigation when known. Do not test against data or systems you do not own or have permission to assess. + ## Repository Map | Path | Purpose | @@ -114,3 +170,5 @@ Please do not open public issues for vulnerabilities. Use GitHub Security Adviso | `workers/live-room-worker.js` | Live Share Durable Object relay. | | `desktop-app/` | Neutralino desktop wrapper and build preparation. | | `wiki/` | Documentation source pages. | + +Related pages: [Installation](Installation.md), [Localization and Terminology](Localization.md), and [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Desktop-App.md b/wiki/Desktop-App.md index 5c99f505..2c840cc3 100644 --- a/wiki/Desktop-App.md +++ b/wiki/Desktop-App.md @@ -1,8 +1,8 @@ -# Desktop Markdown Editor App +# Desktop Markdown Editor Application -The desktop app wraps Markdown Viewer in Neutralinojs for users who want a lightweight local Markdown editor and viewer window. It uses the same editor, preview, renderer, sharing, and export code as the web app, with native file dialogs and local desktop storage. +The desktop application wraps Markdown Viewer in Neutralinojs for users who want a lightweight local Markdown Editor and viewer window. It uses the same Editor, Preview, renderer, sharing, and export code as the web application, with native file dialogs and local desktop storage. -## What Is Different From The Web App? +## What Is Different from the Web Application? - Runs in a Neutralinojs desktop window. - Uses native open/save dialogs for Markdown and HTML. @@ -15,6 +15,8 @@ The desktop app wraps Markdown Viewer in Neutralinojs for users who want a light Network features remain network features: managed media upload, GitHub import, stored Share Snapshot, Live Share, remote diagram rendering, external images, and external links can still contact remote services. +PlantUML and D2 contain an optional local-command code path, but it requires `os.execCommand` plus explicit opt-in. Because the default native allowlist omits that API, the standard desktop build uses the remote PlantUML/Kroki paths. + ## Directory Structure ```text @@ -104,7 +106,7 @@ Browser/chrome modes block filesystem and OS APIs more tightly. - Bundles Bootstrap icon fonts. - Strips web-only SEO/canonical/hreflang/schema metadata from the desktop HTML. -This is why the prepared desktop app can load core bundled renderer libraries without CDNs after setup. +This is why the prepared desktop application can load core bundled renderer libraries without CDNs after setup. ## Platform Notes @@ -131,3 +133,6 @@ chmod +x markdown-viewer-mac_universal - Native file access happens through explicit open/save actions or launch arguments. - The app does not include analytics or telemetry. - Sharing/import/remote-rendering features use the same network behavior as the web app. +- Private mode and **Reset workspace** delete persisted Secret Workspace data as well as normal Document state. + +Related pages: [Installation](Installation.md), [Configuration](Configuration.md), [Privacy and Security](Privacy-and-Security.md), and [Troubleshooting](Troubleshooting.md#the-desktop-application-does-not-start). diff --git a/wiki/Development-Journey.md b/wiki/Development-Journey.md index 9086972e..9e3e4193 100644 --- a/wiki/Development-Journey.md +++ b/wiki/Development-Journey.md @@ -26,8 +26,8 @@ This page keeps the technical record too, but the journey is not only technical. Current sharing behavior separates two clear workflows: -- Share Snapshot creates a read-only or editable point-in-time copy. Small documents stay inside the URL hash. Larger documents are stored in Cloudflare KV for 90 days, with restricted API origins and creator-side deletion tokens. -- Live Share creates a temporary Cloudflare Durable Object room for real-time Yjs collaboration. The room relays updates and presence while active and does not store the document as a permanent record. +- Share Snapshot creates a point-in-time copy with View only or Can edit access. Small documents stay inside the URL hash. Larger documents are stored in Cloudflare KV for 90 days, with restricted API origins and creator-side deletion tokens. +- Live Share creates a Cloudflare Durable Object room for real-time Yjs collaboration. The room relays Markdown/Review updates and presence without persisting Document content server-side; it does persist host/edit/view capability metadata. Recent workspace work added nested folders, GitHub directory preservation, range and multi-item Explorer actions, document-surface context menus, and a two-document split whose previews run the full math, diagram, map, STL, and ABC rendering pipeline. @@ -86,6 +86,8 @@ The changelog records many small fixes. The recurring themes are: - Temporary shared/live tabs are excluded from saved workspaces. - Small snapshot links keep content in the URL hash. - Stored snapshot links use Cloudflare KV for 90 days. -- Private mode prevents normal document-state persistence, and Reset workspace removes saved files and review data. +- Private mode prevents normal Document-state persistence after clearing it, and Reset workspace removes normal files, review data, and Secret Workspace storage. - Live Share uses Cloudflare Durable Objects as temporary relays. - Remote renderer and import features send only the data needed for that feature. + +This page is historical context, not the source of current product behavior. Use [Features](Features.md) and [Privacy and Security](Privacy-and-Security.md) for the current reference. diff --git a/wiki/Docker-Deployment.md b/wiki/Docker-Deployment.md index 9db25091..ec112d06 100644 --- a/wiki/Docker-Deployment.md +++ b/wiki/Docker-Deployment.md @@ -53,17 +53,36 @@ docker run -d --name markdown-viewer-local -p 8080:80 markdown-viewer:local The root `.dockerignore` excludes desktop build output and unrelated local files from the web container. -## What The Container Provides +## What the Container Provides -The container serves the static browser app: editor, preview, local storage, imports, exports, PWA assets, and CDN-loaded renderers. +The container serves the static browser shell: `index.html`, `script.js`, `styles.css`, `sw.js`, `manifest.json`, `robots.txt`, `sitemap.xml`, and `assets/`. It provides the Editor, main-thread Preview, local storage, local imports, most exports, and CDN-loaded renderer libraries. -The container alone does not provide Cloudflare KV or Durable Objects. Stored Share Snapshot and Live Share require Cloudflare deployment or equivalent compatible endpoints. +On `localhost`, managed-media and stored Share Snapshot requests use the production `https://markdownviewer.pages.dev` API. Live Share defaults to the Docker origin and fails unless a compatible `/live-room` endpoint is available or `window.MARKDOWN_VIEWER_LIVE_ROOM_URL` is configured in a custom deployment. + +The container alone does not provide Cloudflare KV or Durable Objects. Self-hosted stored Share Snapshot and Live Share require separately deployed compatible endpoints. + +## Known Stock Image Limitation + +The checked-in root `Dockerfile` does not copy: + +- `preview-worker.js`; or +- `sample.md`. + +Both files are listed in `sw.js` as critical precache assets. The consequences are: + +- Documents eligible for Preview Worker rendering receive a Worker load failure and fall back to main-thread rendering; and +- Service Worker installation can fail because `cache.addAll()` rejects the complete precache when either asset returns `404`. + +This is an implementation packaging limitation, not a documentation configuration step. The documentation audit records it without changing Docker behavior. + +If you maintain a custom image, copy both files to `/usr/share/nginx/html/`, rebuild, and verify that every `CRITICAL_ASSETS` URL in `sw.js` returns `200` with the correct MIME type. ## Nginx and Headers The Docker image uses `nginx:alpine`. Production deployments should keep these behaviors: - Serve `index.html`, `script.js`, `styles.css`, `preview-worker.js`, `sw.js`, `manifest.json`, and `assets/`. +- Serve `sample.md` because the Service Worker includes it in the critical precache. - Serve JavaScript files with correct MIME types. - Allow Service Worker registration from the app origin. - Send security headers that match the app's CSP and deployment policy. The current Docker image includes: @@ -131,9 +150,12 @@ Serving from a sub-path such as `/editor/` requires testing: Root hosting is the simplest and best-tested deployment mode. -## Privacy Notes For Self-Hosting +## Privacy Notes for Self-Hosting - Normal documents stay in the user's browser storage. - Your server will serve static assets and may log normal HTTP requests. - URL-hash Share Snapshot content is not sent to the server as an HTTP fragment, but users can paste links into other systems. - Stored Share Snapshot and Live Share need Cloudflare or compatible services and have their own data flows. +- The stock localhost client sends consented managed-media and stored Share Snapshot requests to the production Markdown Viewer API. + +For the complete boundary, see [Privacy and Security](Privacy-and-Security.md). For diagnostics, see [Troubleshooting](Troubleshooting.md#docker-preview-or-pwa-offline-support-is-incomplete). diff --git a/wiki/FAQ.md b/wiki/FAQ.md index 551cdc09..91019a54 100644 --- a/wiki/FAQ.md +++ b/wiki/FAQ.md @@ -1,171 +1,147 @@ -# Markdown Viewer FAQ +# Frequently Asked Questions ## General ### What is Markdown Viewer? -Markdown Viewer is a browser-based Markdown editor, viewer, reader, and previewer for opening `.md` files, writing in plain Markdown, and using a split-screen live preview with sync scrolling. It also includes document tabs, GitHub-Flavored Markdown, math, diagrams, maps, STL models, ABC music notation, export tools, optional sharing, and a desktop app. +Markdown Viewer is a local-first Markdown editor and viewer with a plain-text Editor, sanitized Preview, Split view, multi-Document Workspace, rich renderers, exports, Share Snapshot, and Live Share. It runs on the web, as a PWA, in Docker, and as a Neutralino desktop application. ### Is it free? -Yes. The project is open source under the Apache License 2.0. +Yes. Markdown Viewer is open source under the [Apache License 2.0](../LICENSE). ### Do I need an account? -No. There is no login, subscription, account system, analytics identity, or cloud workspace account. You can use the editor as a no-signup Markdown reader and previewer. +No. The application has no account, login, or subscription system. -### Is it a WYSIWYG Markdown editor? +### Is it a WYSIWYG editor? -Not in the strict sense. Markdown Viewer is a plain-text Markdown editor with live preview and WYSIWYG-style toolbar helpers. You can quickly insert common formatting, but you do not directly edit the rendered preview like a full rich-text editor. +No. You edit plain Markdown source. The formatting toolbar inserts or transforms Markdown, and Preview shows the rendered result. -### Can it open local .md files? +### Which platforms are supported? -Yes. You can open `.md` and `.markdown` files with the file picker or drag and drop. The desktop app can also open Markdown files through native file dialogs and command-line file arguments. +You can use a modern browser, install the PWA where the browser supports it, self-host the static application, run the Docker image, or use/build the Neutralino desktop application. Exact behavior still depends on browser, webview, operating system, GPU, audio, print engine, and network support. -### How do I organize documents? +## Workspace and Storage -Use the Explorer to create nested folders inside Workspace or the password-protected Secret Workspace. Drag files between locations or use **Move to…**. Ctrl/Cmd-click selects separate items, while Shift-click or Shift+Arrow selects a range for bulk open, move, or delete actions. +### Where are my Documents stored? -## Privacy and Data +Normal Workspace state is stored in browser `localStorage`. The desktop application mirrors selected values into Neutralino storage. Markdown Viewer is not a synchronized cloud Workspace. -### Does my Markdown leave my device? +### How many Documents can I keep? -Normal typing, previewing, local file import, tab autosave, and most exports happen on your device. Content can leave your device when you use explicit network features: +The implemented limit is 50 Documents across normal Workspace, locked Secret Workspace counts, and temporary Share Snapshot/Live Share tabs. -- GitHub import contacts GitHub. -- Remote diagram renderers can receive diagram source. -- Pasting, dropping, or uploading a device image, animated GIF, or supported video sends a managed copy to public media storage after first-use consent. -- Large Share Snapshot links upload a temporary copy to Cloudflare KV. -- Live Share relays real-time updates through Cloudflare Durable Objects. -- External images, links, map tiles, and CDN libraries can be requested by the browser. +### What is the difference between closing and deleting a Document? -### Do you collect analytics or telemetry? +Closing removes the open tab but keeps the Document in the Workspace. Deleting removes the Document. Closing all tabs can leave the Workspace files available in Explorer. -No analytics, telemetry, ads, tracking pixels, or app-specific cookies are implemented in the codebase. +### What happens when I delete a Folder? -### What does the app store locally? +Markdown Viewer moves Documents from that Folder tree to the containing Workspace root, then removes the Folders. A multi-item delete can delete selected Documents while returning Documents from deleted Folders to the root; read the confirmation carefully. -The app stores normal tabs and their review threads, nested folder organization, active tab id, untitled-tab counter, theme/direction/view settings, language selection, scroll sync state, and Find and Replace dock preference. Web storage uses browser `localStorage`; the desktop app mirrors selected values into Neutralino storage. Private mode clears document/workspace state and prevents those document-state keys from being written until it is turned off. +### What is Secret Workspace? -### Are comments and suggestions added to my Markdown? +Secret Workspace encrypts stored file contents and Folder names on the device with a password-derived AES-GCM key. The password cannot be recovered. The protection applies to stored content, not to exports, unlocked sessions, or network features. -No. Review threads are a separate feedback layer attached to rendered blocks. They are excluded from Markdown and document exports. Share Snapshot does not include them; an active Live Share room synchronizes them through its separate Review channel. +### What does Private mode do? -### Are Share Snapshot links private? +Private mode clears persisted Document-state keys, including the encrypted Secret Workspace payload, and blocks further Document-state writes while enabled. Current in-memory work can continue during that session but does not survive reload or exit. -They are bearer links. Anyone with the link can open the snapshot. Large stored snapshots expire after 90 days. The creator-side API response includes a separate deletion token that can be used to delete the stored record before expiry; it is not included in the share URL. +> **Warning:** Export needed Documents before enabling Private mode. -Small snapshots keep compressed content inside the URL hash. Large snapshots use `/api/share`, which stores content, mode, title, creation time, and size in Cloudflare KV for 90 days. Editable snapshots are not collaborative; they only let the recipient edit their opened copy. +### What does Reset workspace delete? -### Are uploaded media links private? +It ends Live Share, deletes normal Documents, review data, and Secret Workspace storage, then restores the welcome Document. Markdown Viewer cannot undo this action. -No. Still images are optimized; images, animated GIFs, and supported videos are uploaded only after first-use consent, then referenced by a short content-addressed HTTPS link. The id is difficult to guess, but anyone who receives the URL can retrieve the media for up to 90 days. Cloudflare KV deletes it after that TTL, so the link stops rendering. Duplicate content reuses the same link and refreshes its 90-day expiry; legacy inline raster data can be converted to managed links after the same consent. The duration is the same 90-day limit used by stored Share Snapshot links, but their storage records are separate. +## Privacy and Security -### Is Live Share saved permanently? +### Does Markdown leave my device? -No. Live Share uses a temporary Cloudflare Durable Object room as a relay. It does not write the live document to KV or a database. While active, the room relays document updates, review comments and suggestions, display names, presence, cursors, sync messages, leave messages, and session-end messages. +Normal editing, local import, Preview, Workspace storage, and most exports stay on the device. Data can leave when you use managed media, public GitHub import, remote diagram rendering, stored Share Snapshot, Live Share, external assets/map tiles, or uncached web libraries. -### Is Live Share end-to-end encrypted? +See [Privacy and Security](Privacy-and-Security.md) for the complete table. -No end-to-end encryption is implemented. The room id and secret are included in the invite link, and the Cloudflare Durable Object relays messages. Treat Live Share links like private bearer links. +### Does Markdown Viewer collect analytics? -### How do I clear local data? +The application code does not implement analytics, telemetry, advertising, tracking pixels, or app-specific cookies. External services, hosting providers, and self-hosted servers can still process normal request logs. -Use **Reset workspace** in Workspace settings to clear saved files and review data. Private mode also clears document/workspace state and prevents it from being saved. Clearing site data from browser settings/developer tools removes cached app assets and any saved settings for that origin. +### Is rendered HTML sanitized? -### What security protections are enabled? +Yes. Preview HTML is sanitized with DOMPurify before insertion. Remote SVG output receives additional filtering. Sanitization reduces risk but is not a guarantee against every browser or third-party defect. -Preview HTML is sanitized, exported HTML uses CSP/SRI protections, Cloudflare Pages sets security headers and hides sensitive paths, Share Snapshot CORS is restricted, Live Share validates origins and capabilities server-side, and the desktop build does not expose Neutralino's command-execution API by default. These protections reduce risk but do not make shared links private or Live Share end-to-end encrypted. +### Are Share Snapshot links private? -## Editing and Rendering +No. They are bearer links. Anyone with the complete link can use its View only or Can edit capability. Stored snapshots expire after 90 days. -### What Markdown does it support? +### Can I delete a stored Share Snapshot early? -It supports standard Markdown, GitHub-Flavored Markdown (GFM), tables, task lists, footnotes, definition lists, superscript, subscript, highlight syntax, raw sanitized HTML, GitHub alerts, YAML frontmatter in exports, LaTeX math, Mermaid, PlantUML, D2, Graphviz, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL, and ABC notation. +The API supports deletion with the token returned at creation. The current UI does not display that token or provide a Delete snapshot action, so normal UI-created snapshots remain until their 90-day expiry. See [Share Snapshot](Share-Snapshot.md). -### Why do some diagrams need the internet? +### Are managed-media URLs private? -Mermaid, Markmap, maps, STL, ABC, and MathJax use client-side libraries. PlantUML, D2, Graphviz, Vega-Lite, WaveDrom, and some insertion previews can use remote renderers such as PlantUML, Kroki, or mermaid.ink. Those remote services need network access and receive the diagram source. +No. They are content-addressed and difficult to guess, but anyone with the URL can retrieve the media until its 90-day expiry. There is no early-delete control. -### Why does the preview update in stages? +### Is Live Share end-to-end encrypted? -Base Markdown renders first. Advanced content such as MathJax, diagrams, maps, STL, ABC, and remote renderers runs after the base HTML has been sanitized and inserted. On large documents the app may use a Web Worker and segmented DOM patching to keep typing responsive. +No. Treat every invitation as a sensitive bearer link. -### Why did a shared document open in a temporary tab? +### Does Live Share store the Document? -Share Snapshot and Live Share tabs are temporary by design. They are stripped from persistent tab storage so opening someone else's link does not silently save their document into your workspace. +It does not persist Markdown or Review content server-side. Connected clients exchange it through a Durable Object WebSocket relay. The Durable Object does persist host/edit/view capability values and `createdAt` without an application TTL or deletion route. -### Can I open two documents side by side? +## Markdown, Renderers, and Editing -Yes. Choose **Open in split view** from a file menu and select the second file. A shared control switches both documents between Edit and Preview. Preview mode renders Markdown, math, Mermaid and remote diagrams, maps, STL models, and ABC notation. This is separate from the normal Editor/Split/Preview modes for one document. +### Which Markdown features are supported? -## Import and Export +Markdown Viewer supports CommonMark-style Markdown, GFM tables/task lists/strikethrough/autolinks, alerts, footnotes, definition lists, syntax highlighting, sanitized HTML, frontmatter handling, math, and the rich fences listed in [Markdown Reference](Markdown-Reference.md). -### Can I import local files? +It is GFM-oriented, not guaranteed to match GitHub, Pandoc, Obsidian, Typora, or another parser byte for byte. -Yes. Import `.md`, `.markdown`, or `text/markdown` files through the file picker or drag and drop. Dropping onto an Explorer folder imports there; untargeted drops use the Workspace root. The app scans the first 8 KB for null bytes and rejects likely binary files. +### Which renderers send source over the network? -### Can I import private GitHub repositories? +PlantUML uses the PlantUML server with Kroki fallback. D2, Graphviz/DOT, Vega-Lite, and WaveDrom use Kroki. Some insertion previews use mermaid.ink or Kroki. Do not use those paths for sensitive source unless you trust the service. -No. The GitHub importer only uses public GitHub URLs and does not ask for tokens. +### Can I compare two Documents? -### Why are only 30 GitHub files shown? +Yes. Use **Open in split view** from a Document menu, then choose a second Document. A shared control switches both sides between Edit and Preview. This two-Document mode is separate from the single-Document Editor/Split view/Preview controls. -The importer limits repository/folder results to the first 30 Markdown files to keep the modal and network requests manageable. Imported files go into a repository-named folder and keep their nested GitHub directory paths. +### Does Find and Replace support regular expressions? -### Which PDF export should I use? +Yes. It supports regular expressions, capture replacements, preserve-case replacement, selection-only matching, selected syntax scopes, and a diff Preview. Scope detection is best-effort for unusual Markdown. -Use Browser Print for most documents. It is faster and better for long text, and it always prepares a light print theme even if the app is currently in dark mode. Use Legacy Raster PDF when you need the app's page-break planning for images, tables, math, and diagrams, but expect higher memory use and possible browser canvas limits. +## Import and Export -### Why are images missing from PDF or PNG export? +### Which local files can I import? -Canvas-based exports require images to be loaded and CORS-compatible. A remote image that blocks cross-origin canvas capture may not appear in raster PDF/PNG output. +`.md`, `.markdown`, and `text/markdown` files up to 10 MB. The application scans the first 8 KiB for null bytes and rejects likely binary content. -### Why does exported PDF differ from the preview? +### Can I import a private GitHub repository? -Browser Print depends on the browser print engine. Legacy Raster PDF captures an off-screen layout to canvas, applies page-break changes, scales some content, and may move blocks to avoid bad page cuts. That can differ from the live preview. +No. The importer uses public GitHub URLs and does not request a token. Repository and Folder results show at most 30 Markdown files. -Browser Print removes the app's dark-mode styling before printing and restores it afterward. It does not rewrite colors that were intentionally placed in your Markdown, embedded HTML, SVG, image files, or diagram source. +### Which PDF option should I use? -## Installation and Offline Use +Use Browser Print for most long, text-heavy Documents and selectable text. Use Legacy Raster PDF when screenshot-style capture and its page-break planning are more important. Raster export consumes more memory and depends on browser canvas/CORS behavior. -### Can I run it offline? +### Why are images missing from PDF or PNG? -Yes, with limits. +Canvas-based exports need successfully loaded, CORS-compatible resources. A remote image that blocks cross-origin canvas access can be omitted. Wait for all assets/renderers, then see [Troubleshooting](Troubleshooting.md#pdf-or-png-export-is-missing-content). -- The web/PWA build can work offline after the app shell and CDN libraries have been loaded and cached. -- First use of CDN-based libraries still requires network access unless they are already cached. -- The prepared desktop build bundles external libraries into `resources/libs` and points dynamic library loading there. -- Features that inherently use the network, such as managed media upload, GitHub import, stored Share Snapshot, Live Share, remote diagram rendering, and external images, still need connectivity. +## Installation and Offline Use ### Can I open `index.html` directly? -Use a local server instead. `file://` can block Web Workers and Service Workers, which breaks important rendering and offline behavior. Run `python -m http.server 8080` or `npx serve . -p 8080`. - -### Why will the desktop app not launch on macOS? - -The binaries are unsigned, so macOS may quarantine them. You can right-click and choose Open, or run: - -```bash -xattr -d com.apple.quarantine markdown-viewer-mac_universal -chmod +x markdown-viewer-mac_universal -./markdown-viewer-mac_universal -``` - -## Troubleshooting - -### The preview is blank. What should I check? - -Check the browser console for blocked scripts or network errors, verify JavaScript is enabled, and hard refresh. If you are using `file://`, serve the app from localhost instead. +Use an HTTP server instead. `file://` can block Web Workers and Service Workers. -### Math does not render. Why? +### Can the PWA work offline? -MathJax loads when math markers are detected. Check your LaTeX syntax and network/cache state if this is the first time using math in the web build. +The application shell and previously fetched CDN libraries can work after a successful Service Worker installation and cache fill. First-use libraries and every network-backed feature still require connectivity. -### Mermaid or another diagram shows an error. What now? +### Does Docker include Share Snapshot and Live Share backends? -Check the fence language and diagram syntax. For remote diagram engines, also check network access to the renderer. Remote requests time out and retry, but they cannot render while the service is unreachable. +No. The container is a static Nginx site. It does not provide Cloudflare KV or Durable Objects. The stock image also omits `preview-worker.js` and `sample.md`, which limits Worker and PWA/offline behavior. See [Docker Deployment](Docker-Deployment.md#known-stock-image-limitation). -### Live Share says the room expired. +## Help -The room may have ended, the host may have left, the invite may be stale, or the participant may not have received initial sync within the join timeout. Ask the host to start a new session. +For diagnostic steps, use [Troubleshooting](Troubleshooting.md). For an unresolved reproducible problem, search or open a [GitHub issue](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) without including confidential Documents, bearer links, secrets, capabilities, or tokens. diff --git a/wiki/Features.md b/wiki/Features.md index a9d81f46..a140ad20 100644 --- a/wiki/Features.md +++ b/wiki/Features.md @@ -4,7 +4,7 @@ This page is the source-of-truth feature reference for Markdown Viewer. It descr ## Product Summary -Markdown Viewer is a browser-based Markdown editor, viewer, reader, and previewer for opening `.md` and `.markdown` files, writing plain Markdown, and reading a live GitHub-style preview. It runs as a static web app, a Progressive Web App, a Docker-hosted static site, and a Neutralino desktop app. The editor is built around a plain textarea, a split-screen rendered preview pane with sync scrolling, document tabs, import/export tools, sharing tools, rich Markdown renderers, and optional Cloudflare endpoints for Share Snapshot and Live Share. +Markdown Viewer is a browser-based Markdown editor and viewer for opening `.md` and `.markdown` files, writing plain Markdown, and reading a live GitHub-style Preview. It runs as a static web application, a Progressive Web App, a Docker-hosted static site, and a Neutralino desktop application. The Editor is built around a plain textarea, a rendered Preview pane in Split view with sync scrolling, Document tabs, import/export tools, sharing tools, rich Markdown renderers, and optional Cloudflare endpoints for Share Snapshot and Live Share. Most work happens in the browser or desktop webview. Markdown parsing, syntax highlighting, math rendering, diagram post-processing, PDF/PNG capture, tab storage, undo/redo, search, and formatting tools are client-side. The exceptions are explicit network features: GitHub import, emoji lookup, CDN library loading in the web build, remote diagram fallback services, large Share Snapshot storage, and Live Share relay rooms. @@ -15,11 +15,11 @@ The app opens with a header, Files sidebar, document tab bar, formatting toolbar - The left **Files** sidebar organizes Markdown files into fixed **Workspace** and **Secret Workspace** roots with nested folders, All files, Recent, Favorites, and search views. - The sidebar is resizable and collapsible on desktop, narrower on tablet, and becomes a full-height drawer on mobile. - Editor mode shows only the textarea. -- Split mode shows the editor and preview side by side. +- Split view shows the Editor and Preview side by side. - Preview mode shows only the rendered document. - A file menu can open a second document beside the active document. A shared control switches both sides between Edit and Preview, and synchronized scrolling is optional. - On small screens, the mobile menu exposes the same core actions and the layout avoids a cramped split view. -- A draggable divider resizes editor and preview in split mode and keeps both panes above 20% width. +- A draggable divider resizes the Editor and Preview in Split view and keeps both panes above 20% width. - The divider also supports keyboard adjustment with left and right arrow keys while split view is active. - The GitHub link in the header opens the source repository. - The bottom status bar centers reading time, word count, and character count, while its right edge reports Saving or All changes saved. @@ -44,7 +44,7 @@ Users can work with multiple documents at once. - Each normal tab stores a title, content, workspace/folder location, favorite state, recent activity metadata, scroll position, view mode, local review threads, and creation time. - The active tab id and untitled-document counter are stored separately. - Temporary Share Snapshot and Live Share tabs are deliberately excluded from persistent tab storage. -- **Reset workspace** clears saved files and review data and returns the app to a clean starting state. +- **Reset workspace** clears normal files, review data, and Secret Workspace storage, ends Live Share, and returns the app to a clean starting state. Storage keys used by the current implementation include: @@ -59,9 +59,9 @@ Storage keys used by the current implementation include: | `app-lang` | Selected interface language. | | `find-replace-docked` | Whether the Find and Replace panel is docked. | -On the web, these values live in browser `localStorage`. In the desktop app, the code mirrors selected localStorage values into Neutralino storage, so preferences and workspace state survive desktop restarts. +On the web, these values live in browser `localStorage`. In the desktop application, the code mirrors selected `localStorage` values into Neutralino storage, so preferences and Workspace state survive desktop restarts. -Workspace settings includes **Private mode**, which removes saved document/workspace state and prevents normal document-state keys from being written while it is enabled. The private-mode preference itself remains so the behavior survives a reload. **Reset workspace** removes files and review data and returns the application to a clean workspace. The About dialog describes storage privacy but does not duplicate these controls. +Workspace settings includes **Private mode**, which removes saved document/workspace state and prevents normal document-state keys from being written while it is enabled. The cleared keys include the encrypted Secret Workspace payload. The private-mode preference itself remains so the behavior survives a reload. **Reset workspace** removes normal files, review data, and Secret Workspace storage before returning the application to a clean Workspace. Export needed Documents before either action; Markdown Viewer cannot recover deleted storage. The About dialog describes storage privacy but does not duplicate these controls. ## Comments and Suggestion Mode @@ -192,7 +192,7 @@ Limitations: ## Insert Diagrams, Charts, Maps, Models, and Music -Markdown Viewer supports many fenced-code renderers, so it can work as a Markdown diagram editor, Mermaid editor, PlantUML editor, Graphviz/DOT editor, D2 diagram editor, Vega-Lite chart previewer, Markmap mind map viewer, WaveDrom timing diagram viewer, ABC notation viewer, map previewer, and 3D STL viewer. +Markdown Viewer supports many fenced-code renderers for diagrams, charts, mind maps, digital timing diagrams, music notation, geographic maps, and 3D STL models. | Fence Language | Renderer | User Behavior | Network Notes | | :--- | :--- | :--- | :--- | @@ -235,6 +235,7 @@ Local file import: - Accepts `.md`, `.markdown`, and `text/markdown`. - Extension checks are case-insensitive. +- Rejects an individual Markdown file larger than 10 MB. - Dragging files over the app shows a compact drop notice. Explorer document drags use a Markdown file preview, folders expand on hover, and the Explorer scrolls near its top and bottom edges. - The first 8 KB of a file are scanned for null bytes to avoid loading binary files as text. - Imported local files open in the active tab or a new tab depending on the action. @@ -269,7 +270,7 @@ GitHub import: Limitations and privacy: -- Local file content is read in the browser or desktop app and is not uploaded by local import. +- Local file content is read in the browser or desktop application and is not uploaded by local import. - GitHub import sends repository and path information to GitHub and downloads public file contents from GitHub. - Private GitHub repositories are not supported because the app does not ask for tokens. @@ -281,7 +282,7 @@ Markdown export: - Saves the raw Markdown text. - In the web app, it downloads through the browser. -- In the desktop app, it uses a native save dialog and Neutralino filesystem writing. +- In the desktop application, it uses a native save dialog and Neutralino filesystem writing. HTML export: @@ -321,7 +322,7 @@ Share Snapshot creates a link to a point-in-time copy of the current document. Modes: - View only opens the shared content in preview mode with the editor hidden. -- Editable opens the shared content in split mode so the recipient can edit their own copy. +- Can edit opens the shared content in Split view so the recipient can edit their own copy. Storage behavior: @@ -333,17 +334,18 @@ Storage behavior: - The server accepts up to 8,000,000 characters per stored snapshot. - Snapshot ids are random 10-character values using a reduced alphabet and must match the app's id pattern. - Stored snapshot responses use `Cache-Control: no-store`. -- The Share API allows CORS only for the production app, `null`, and `localhost`/`127.0.0.1` development origins; unsupported origins are rejected. +- The Share API allows CORS for the production app, HTTPS `*.markdownviewer.pages.dev` previews, `null`, and `localhost`/`127.0.0.1` development origins; unsupported browser origins are rejected. - Creating a stored snapshot returns a creator-side deletion token. The token is hashed in KV and is required for `DELETE /api/share/`; it is not part of the share URL. +- The current UI retains that token only in memory and does not display it or provide an early-delete action. An API client must capture the creation response if it needs to delete the stored record before expiry. - Shared snapshot tabs are temporary and are not saved to the recipient's local workspace. Privacy implications: - URL-hash snapshots keep document content inside the link itself. - Anyone with a snapshot link can read the snapshot. -- Editable snapshot links are not collaborative; they only let the recipient edit their local opened copy. +- Can edit snapshot links are not collaborative; they only let the recipient edit their local opened copy. - Stored snapshots upload document content, mode, title, creation time, and size to the configured Cloudflare KV namespace until expiry. -- The app prevents sharing a temporary shared snapshot again, and prevents Share Snapshot from a Live Share document, to avoid confusing copies of copies. +- The app prevents sharing a temporary snapshot again. A Live Share participant cannot create a snapshot from the live Document; the host can. ## Live Share Rooms for Markdown Collaboration @@ -369,7 +371,7 @@ Implementation: - The host connection establishes separate host, edit, and view capabilities. The Durable Object stores these capabilities and authenticates each joining role server-side. - Cloudflare Pages routes the WebSocket to a Durable Object named `LIVE_ROOMS`. - The Durable Object relays only known message types and filters them by role: viewers cannot send Markdown updates or session-end messages, but they can request and send Review updates; editors can send Markdown and Review updates; only the host can publish full Review state or send every supported type. -- The Durable Object does not write document state to KV or a database. +- The Durable Object does not persist Markdown or Review document state. It does persist the host, edit, and view bearer capability values plus `createdAt` in Durable Object storage under `live-room-auth-v1`. - Room identity is derived from room id plus secret. Limits: @@ -378,14 +380,14 @@ Limits: - A live room can have at most 64 WebSocket participants. - Participant presence is considered stale after 45 seconds without updates. - Join waits up to 8 seconds for initial room state before showing an expired/unavailable room message. -- The room exists only while the Durable Object instance and connected sessions are alive. +- A participant needs an active client, normally the host, to supply initial Yjs document state. The server does not retain a document copy for later recovery. Privacy implications: - Live Share document updates, display names, cursor positions, and presence are transmitted through the configured Cloudflare Durable Object. -- Live room content is temporary relay state, not permanent document storage. +- Live Markdown and Review content is temporary relay/client state, not permanent server-side document storage. Capability metadata is durable and has no application TTL or deletion route. - Anyone with the invite URL, including the secret, can join while the room is active. -- View-only and editable roles are checked by the Durable Object, which filters message types by capability. Invite URLs still contain bearer credentials, and Live Share is not end-to-end encrypted. +- View only and Can edit roles are checked by the Durable Object, which filters message types by capability. Invite URLs still contain bearer credentials, and Live Share is not end-to-end encrypted. ## Clipboard and Copy Behavior @@ -436,7 +438,7 @@ Common shortcuts: | Save/export Markdown | `Ctrl+S` / `Cmd+S` | | Find | `Ctrl+F` / `Cmd+F` | | Replace | `Ctrl+H` / `Cmd+H` | -| Toggle scroll sync | `Ctrl+Shift+S` / `Cmd+Shift+S` in split mode | +| Toggle scroll sync | `Ctrl+Shift+S` / `Cmd+Shift+S` in Split view | | Undo | `Ctrl+Z` / `Cmd+Z` | | Redo | `Ctrl+Shift+Z`, `Cmd+Shift+Z`, `Ctrl+Y`, or `Cmd+Y` | | New tab | Desktop: `Ctrl+T` / `Cmd+T`; web and desktop: `Alt+Shift+T` | @@ -470,8 +472,9 @@ Limitations: - First use of CDN-based renderers requires network access unless already cached. - Clearing site data removes the cached app shell and local documents. - Opening `index.html` through `file://` can break workers and service workers because of browser security rules. +- The checked-in root Dockerfile does not copy `preview-worker.js` or `sample.md`, although the Service Worker precache requires both. The stock container therefore falls back to main-thread Preview for large Documents and can fail Service Worker installation until the image is corrected. -## Desktop App +## Desktop Application The desktop build wraps the same app in Neutralino. @@ -508,7 +511,7 @@ Important protections: - Canvas exports use `allowTaint: false`. - STL rendering validates source size, finite vertex coordinates, and geometry vertex count before creating a WebGL view. - The desktop native API allowlist follows least privilege for the app's current features. -- Private mode and Reset workspace provide explicit controls over local document persistence. +- Private mode and Reset workspace provide explicit controls over local document persistence, but both delete persisted Secret Workspace content in the current implementation. - Share and live endpoints return no-store responses for dynamic content. - The app does not include analytics, telemetry scripts, ad pixels, accounts, cookies, or subscription code. @@ -517,7 +520,7 @@ Security limitations: - Sanitization reduces XSS risk but cannot make every third-party renderer or browser bug impossible. - Remote diagram services receive diagram source for supported remote engines. - Links and images in Markdown can request external resources when rendered or clicked. -- Live Share roles are server-checked, but invite links are bearer credentials and room content is not end-to-end encrypted. +- Live Share roles are server-checked, but invite links are bearer credentials, room content is not end-to-end encrypted, and persisted capability metadata has no application TTL or deletion path. - Share Snapshot links are bearer links: possession of the URL grants access. - Security headers and CSP depend on the deployment surface; self-hosters should preserve the policies in `_headers` and review the Docker/Nginx policy when customizing it. @@ -528,7 +531,7 @@ Security limitations: | Typing and local preview | No | Browser memory and saved tabs | Sanitized before preview insertion. | | Normal tab autosave | No | `localStorage` or desktop storage mirror | Cleared with site/app data or Reset. | | Comments and suggestions | Only during Live Share | Normal saved tabs plus temporary Live Share relay state | Excluded from document exports and Share Snapshot; synchronized between active Live Share participants. | -| Private mode | No | No document-state persistence | Clears existing document state when enabled and prevents normal document-state writes until disabled. | +| Private mode | No | No document-state persistence | Clears existing document state, including Secret Workspace storage, when enabled and prevents normal document-state writes until disabled. | | Local file import | No | Current tab/workspace | Reads selected files only. | | Managed media upload | Yes, after first-use consent | Cloudflare KV, content-addressed, 90-day TTL | Publicly retrievable by its unguessable HTTPS URL until expiry; still images 300 KiB optimized, GIF 5 MiB, video 10 MiB. | | Markdown/HTML/PDF/PNG export | No, except remote assets already referenced | User download location | Browser may request external images/fonts used by content. | @@ -538,17 +541,21 @@ Security limitations: | Remote diagram engines | Yes | Third-party renderer response/cache | Source is sent to PlantUML, Kroki, or mermaid.ink depending on renderer/preview. | | Share Snapshot hash link | Only when user sends the link | Inside URL hash | Small documents are not uploaded by generation. | | Stored Share Snapshot | Yes | Cloudflare KV for 90 days | Content, mode, title, createdAt, and size. | -| Live Share | Yes | Cloudflare Durable Object relay memory | Temporary while active; no KV/database write. | +| Live Share | Yes | Client/WebSocket relay state plus Durable Object capability storage | Markdown and Review content are not persisted server-side; role capabilities and `createdAt` are stored without an application TTL. | | Desktop native storage | No | Local app storage | Mirrors app state for restart persistence. | ## Known Technical Limits - Browser storage quotas can reject very large saved workspaces. - The workspace can contain at most 50 documents, including locked Secret Workspace counts and temporary shared/live tabs. +- An individual local Markdown import is limited to 10 MB. - The GitHub importer shows a maximum of 30 Markdown files. - Stored Share Snapshot content is limited to 8,000,000 characters. Managed media remains separate and travels as short HTTPS links. +- The current Share Snapshot UI does not expose its API deletion token, so UI-created stored snapshots normally remain until their 90-day expiry. - STL source is limited to 2 MiB and parsed geometry to 300,000 vertices. - Legacy raster PDF and PNG exports can fail on extremely tall documents because canvas size and memory are browser-limited. - Remote renderer availability depends on third-party services and network conditions. - The service worker cannot cache assets that have never been successfully fetched. -- The desktop app depends on the platform webview and Neutralino runtime behavior. +- The desktop application depends on the platform webview and Neutralino runtime behavior. + +Related pages: [Usage Guide](Usage-Guide.md), [Markdown Reference](Markdown-Reference.md), [Share Snapshot](Share-Snapshot.md), [Live Share](Live-Share-Cloudflare.md), [Privacy and Security](Privacy-and-Security.md), and [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Home.md b/wiki/Home.md index 61bd2657..4ca0e352 100644 --- a/wiki/Home.md +++ b/wiki/Home.md @@ -1,60 +1,84 @@ -# Markdown Viewer Wiki: Online Markdown Editor, Live Preview, Diagrams, and Export +# Markdown Viewer Documentation -Welcome to the documentation for Markdown Viewer. Markdown Viewer is a browser-based Markdown editor, viewer, reader, and previewer for opening `.md` and `.markdown` files, writing plain Markdown, and reading a split-screen live preview with sync scrolling. It includes a nested document Explorer, a fully rendered two-document split, GitHub-Flavored Markdown, comments and suggestions, rich visual renderers, Markdown-to-PDF/HTML/PNG exports, Share Snapshot links, Live Share rooms, a PWA-capable web build, Docker deployment, and a lightweight Neutralinojs desktop build. +Markdown Viewer is a local-first Markdown editor and viewer for the web, Progressive Web App (PWA), Docker, Cloudflare, and Neutralino desktop application. It provides a plain-text Editor, sanitized Preview, Split view, a multi-Document Workspace, review tools, rich renderers, exports, Share Snapshot, and Live Share. -Most editing and rendering happens on your own device. The important exceptions are documented clearly: GitHub import contacts GitHub, remote diagram fallbacks contact third-party renderers, consented media uploads and large Share Snapshot links use temporary Cloudflare KV storage, and Live Share relays temporary collaboration updates through Cloudflare Durable Objects. The web deployment also applies CSP and security headers, while the desktop build uses a restricted native API allowlist. +Most editing and rendering happens on the device. Managed media, GitHub import, remote diagram services, stored Share Snapshot, Live Share, external assets, map tiles, and uncached web libraries use the network. Read [Privacy and Security](Privacy-and-Security.md) before using those features with sensitive content. ## Start Here -| Need | Page | +| I want to… | Start with | | :--- | :--- | -| Learn every feature, limitation, and data-handling detail | [Features](Features) | -| Use the editor day to day | [Usage Guide](Usage-Guide) | -| Add and manage comments or suggestions | [Usage Guide: Comments and Suggestions](Usage-Guide#comments-and-suggestions) | -| Write supported Markdown, math, diagrams, maps, STL, and ABC notation | [Markdown Reference](Markdown-Reference) | -| Install locally, in Docker, or as a desktop app | [Installation](Installation) | -| Tune deployment and runtime settings | [Configuration](Configuration) | -| Deploy with Docker and reverse proxies | [Docker Deployment](Docker-Deployment) | -| Build and understand the Neutralino desktop app | [Desktop App](Desktop-App) | -| Understand Live Share on Cloudflare | [Live Share Cloudflare](Live-Share-Cloudflare) | -| Add or maintain interface languages | [Localization](Localization) | -| Review project history and design decisions | [Development Journey](Development-Journey) | -| Answer common privacy and troubleshooting questions | [FAQ](FAQ) | -| Contribute changes | [Contributing](Contributing) | - -## Quick Run Options - -| Method | Command | URL | -| :--- | :--- | :--- | -| Python static server | `python -m http.server 8080` | `http://localhost:8080` | -| Node static server | `npx serve . -p 8080` | `http://localhost:8080` | -| Docker Compose | `docker compose up -d` | `http://localhost:8080` | -| Docker image | `docker run -d --name markdown-viewer -p 8080:80 ghcr.io/thisis-developer/markdown-viewer:latest` | `http://localhost:8080` | -| Desktop app | Download from GitHub Releases or build from `desktop-app/` | Desktop window | - -Run local web builds through `localhost` or another HTTP(S) server. Opening `index.html` with `file://` can break Web Workers and Service Workers because browsers block those APIs from local files. - -## Product Principles - -| Principle | What It Means | +| Understand the product and its limits | [Features](Features.md) | +| Learn the Workspace, Editor, Preview, and shortcuts | [Usage Guide](Usage-Guide.md) | +| Write Markdown, math, diagrams, maps, STL, or ABC notation | [Markdown Reference](Markdown-Reference.md) | +| Create a point-in-time link | [Share Snapshot](Share-Snapshot.md) | +| Collaborate in a temporary room | [Live Share](Live-Share-Cloudflare.md) | +| Review local storage, network, retention, and security boundaries | [Privacy and Security](Privacy-and-Security.md) | +| Run the web app, PWA, Docker, Cloudflare, or desktop build | [Installation](Installation.md) | +| Configure storage, libraries, limits, or Cloudflare bindings | [Configuration](Configuration.md) | +| Deploy behind Docker and a reverse proxy | [Docker Deployment](Docker-Deployment.md) | +| Build or operate the Neutralino application | [Desktop Application](Desktop-App.md) | +| Fix a problem | [Troubleshooting](Troubleshooting.md) or [FAQ](FAQ.md) | +| Contribute code, documentation, or a translation | [Contributing](Contributing.md) | +| Maintain interface translations and approved terms | [Localization and Terminology](Localization.md) | +| Read project history and design context | [Development Journey](Development-Journey.md) | + +## Quick Run + +From the repository root: + +```bash +python -m http.server 8080 +``` + +Open `http://localhost:8080`. Use HTTP(S), not `file://`, so Web Workers and Service Workers can run. + +Other supported entry points: + +| Target | Command or action | | :--- | :--- | -| On-device editing | Normal typing, preview, tabs, exports, themes, and settings stay on the user's device. No login is required. | -| Explicit network features | Any feature that sends content elsewhere is user-triggered or tied to a renderer/importer that is documented. | -| Rich Markdown support | The live preview supports GFM tables/task lists, math, footnotes, alerts, Mermaid, PlantUML, Graphviz, D2, Vega-Lite, Markmap, WaveDrom, maps, STL, ABC notation, and more. | -| Responsive performance | Large documents use debounced rendering, optional worker rendering, DOM patching, and cached measurements. | -| Deploy anywhere | The app can run as static files, a PWA, a Docker container, or a lightweight Neutralinojs desktop build. | - -## Privacy At A Glance - -- No accounts, cookies, analytics, ads, or telemetry are implemented. -- Normal documents and settings are stored in browser localStorage or local desktop storage. -- Comments and suggestions stay with normal local tabs, are excluded from exports and Share Snapshot, and synchronize only during an active Live Share room. -- Private mode in Workspace settings clears document state and prevents normal document-state persistence until it is turned off; Reset workspace removes files and review data without enabling Private mode. -- Small Share Snapshot links keep compressed content in the URL hash. -- Large Share Snapshot links upload the snapshot to Cloudflare KV for up to 90 days and remain bearer links for anyone who has the URL. -- Images, animated GIFs, and supported videos are uploaded only after first-use consent. Their unguessable public links expire 90 days after the latest upload of the same content. -- Live Share sends real-time updates, display names, cursors, and presence through a Cloudflare Durable Object while the room is active. -- Live Share host, edit, and view capabilities are authenticated server-side, and unsupported WebSocket origins are rejected. -- Remote diagram renderers receive diagram source when PlantUML, D2, Graphviz, Vega-Lite, WaveDrom, or some preview helpers need them. - -For the complete table of data flows, see [Features](Features#data-handling-summary). +| Hosted web app | Open [markdownviewer.pages.dev](https://markdownviewer.pages.dev/) | +| PWA | Open the HTTPS site and use the browser's install action | +| Docker image | `docker run -d --name markdown-viewer -p 8080:80 ghcr.io/thisis-developer/markdown-viewer:latest` | +| Docker Compose | `docker compose up -d` | +| Desktop development | Run `npm install` and `npm run dev` in `desktop-app/` | +| Desktop build | Run `npm run build` in `desktop-app/` | + +See [Installation](Installation.md) before deploying. The stock Docker image has a documented Worker/PWA packaging limitation. + +## Product Boundaries + +| Area | Implemented behavior | +| :--- | :--- | +| Workspace | Up to 50 Documents, nested Folders, Recent, Favorites, search, tabs, bulk actions, and encrypted Secret Workspace | +| Editing | Editor, Split view, Preview, formatting toolbar, custom undo/redo, Find and Replace, LTR/RTL, large-Document rendering paths | +| Markdown | CommonMark-style parsing, GFM, tables, tasks, alerts, footnotes, definitions, highlighting, sanitized HTML, and math | +| Visual content | Mermaid, PlantUML, Graphviz/DOT, D2, Vega-Lite, WaveDrom, Markmap, GeoJSON, TopoJSON, STL, and ABC | +| Import/export | Local and public GitHub import; Markdown, HTML, Browser Print, legacy raster PDF, and PNG export | +| Sharing | URL-hash or KV-backed Share Snapshot; WebSocket Live Share with host/edit/view capabilities | +| Delivery | Static web, PWA, Docker, Cloudflare, and seven Neutralino desktop targets | + +## Privacy at a Glance + +- Normal Workspace state is local to the browser profile or desktop storage. +- Private mode clears persisted Document state, including Secret Workspace storage, and blocks further persistence while enabled. +- **Reset workspace** deletes normal and Secret Workspace data and cannot be undone in Markdown Viewer. +- Managed media is public-by-link and expires 90 days after the most recent upload of identical content. +- Stored Share Snapshot content remains in Cloudflare KV for 90 days. +- Live Share does not persist Markdown/Review content server-side, but its Durable Object stores role capability metadata without an application TTL. +- The application does not implement end-to-end encryption for sharing. +- The codebase does not implement accounts, analytics, telemetry, advertising, tracking pixels, or app-specific cookies. + +For the complete data-flow table and limitations, see [Privacy and Security](Privacy-and-Security.md). + +## Languages + +The interface supports 14 locales. Maintained documentation entry points are available in: + +- [English](../README.md) +- [Japanese](../locales/README_ja.md) +- [Korean](../locales/README_ko.md) +- [Simplified Chinese](../locales/README_zh.md) +- [Traditional Chinese](../locales/README_tw.md) + +Detailed Wiki pages are maintained in English. Localized READMEs identify English links rather than pointing to missing localized pages. diff --git a/wiki/Installation.md b/wiki/Installation.md index b15421a5..596b8095 100644 --- a/wiki/Installation.md +++ b/wiki/Installation.md @@ -1,6 +1,6 @@ # Install Markdown Viewer: Browser, Docker, Cloudflare, and Desktop -Markdown Viewer is a browser-based Markdown editor and viewer that can run as a static web app, a self-hosted Docker site, a Cloudflare deployment with optional sharing features, or a Neutralino desktop app. Choose the setup that matches how you want to open, read, edit, preview, and export Markdown files. +Markdown Viewer is a browser-based Markdown editor and viewer that can run as a static web application, a self-hosted Docker site, a Cloudflare deployment with optional sharing features, or a Neutralino desktop application. Choose the setup that matches how you want to open, read, edit, preview, and export Markdown files. ## Requirements @@ -30,7 +30,18 @@ npx serve . -p 8080 Open `http://localhost:8080`. -This runs the editor, split live preview, sync scrolling, local storage, local `.md` file imports, exports, PWA registration, and CDN-loaded renderers. The default local client sends consented managed-media uploads to the production image/media API. Other Cloudflare-only features such as stored Share Snapshot and Live Share require their matching deployed endpoints. +This runs the Editor, Split view, live Preview, sync scrolling, local storage, local `.md` file imports, exports, PWA registration, and CDN-loaded renderers. The default local client sends consented managed-media uploads to the production image/media API. Other Cloudflare-only features such as stored Share Snapshot and Live Share require their matching deployed endpoints. + +An individual local Markdown import is limited to 10 MB. See [Features: Known Technical Limits](Features.md#known-technical-limits) for the other enforced limits. + +## Install as a PWA + +1. Open the application over HTTPS or `localhost`. +2. Wait for the first page load and Service Worker registration. +3. Use the browser's **Install** or **Add to Home Screen** action. +4. Launch the installed application once while online and open any renderer you expect to use offline so its CDN libraries can be cached. + +The PWA is offline-capable, not fully offline on first use. Network-backed sharing, import, media, remote diagrams, external assets, and map tiles always need connectivity. ## Docker @@ -60,6 +71,8 @@ docker compose up -d --build The Docker image serves static files with Nginx. It does not magically provide Cloudflare KV or Durable Objects; deploy those separately if you want stored Share Snapshot or Live Share. +> **Known limitation:** The checked-in root `Dockerfile` does not copy `preview-worker.js` or `sample.md`, while `sw.js` expects both during critical precache. The stock image can use main-thread Preview fallback, but large-Document Worker rendering and PWA/offline installation are incomplete. This documentation audit does not change Docker behavior. See [Docker Deployment](Docker-Deployment.md#known-stock-image-limitation). + ## Static Hosting Serve at least these root files: @@ -96,9 +109,9 @@ Deploy the live room worker with: wrangler deploy -c wrangler.live-room.toml ``` -Then deploy the Pages project with `wrangler.toml` or your Cloudflare Pages configuration. See [Live Share Cloudflare](Live-Share-Cloudflare) and [Configuration](Configuration). +Then deploy the Pages project with `wrangler.toml` or your Cloudflare Pages configuration. See [Live Share](Live-Share-Cloudflare.md) and [Configuration](Configuration.md). -## Desktop App +## Desktop Application From `desktop-app/`: @@ -126,7 +139,9 @@ The development and build commands run setup automatically. Setup: - Rewrites dynamic renderer library paths to local `/libs/...` files. - Prepares bundled renderer and export libraries for local desktop loading after setup. -The desktop app uses native open/save dialogs for Markdown and HTML files, asks before closing, and can load a Markdown file passed as a command-line argument. +See [Desktop Application](Desktop-App.md) for output names, native permissions, and platform launch notes. + +The desktop application uses native open/save dialogs for Markdown and HTML files, asks before closing, and can load a Markdown file passed as a command-line argument. ## Offline Use @@ -160,3 +175,27 @@ xattr -d com.apple.quarantine markdown-viewer-mac_universal chmod +x markdown-viewer-mac_universal ./markdown-viewer-mac_universal ``` + +Run quarantine-removal commands only for a binary you trust. + +## Official Platform Documentation + +- [Docker documentation](https://docs.docker.com/) +- [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/functions/) +- [Cloudflare Workers KV](https://developers.cloudflare.com/kv/) +- [Cloudflare Durable Objects](https://developers.cloudflare.com/durable-objects/) +- [Neutralinojs documentation](https://neutralino.js.org/docs/) + +These upstream pages describe their platforms. Markdown Viewer-specific commands, bindings, and limitations remain documented in this Wiki. + +## Validate an Installation + +- Open a local `.md` file smaller than 10 MB. +- Switch among Editor, Split view, and Preview. +- Render one client-side fence such as `mermaid` and one remote fence such as `graphviz` if remote rendering is intended. +- Export Markdown and HTML. +- Confirm Service Worker registration only on HTTPS or localhost. +- For Cloudflare, create a stored Share Snapshot and test a Live Share room from a second browser profile. +- For desktop, test native open/save and verify that `os.execCommand` remains unavailable in the default build. + +If a check fails, use [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Live-Share-Cloudflare.md b/wiki/Live-Share-Cloudflare.md index 69560928..30987264 100644 --- a/wiki/Live-Share-Cloudflare.md +++ b/wiki/Live-Share-Cloudflare.md @@ -1,6 +1,6 @@ # Live Share Rooms for Markdown Collaboration on Cloudflare -Live Share is the temporary Markdown collaboration feature in Markdown Viewer. It is separate from Share Snapshot. Share Snapshot creates a point-in-time link; Live Share creates a temporary WebSocket room. +Live Share is the temporary Markdown collaboration feature in Markdown Viewer. It is separate from Share Snapshot. Share Snapshot creates a point-in-time link; Live Share relays Yjs updates through a WebSocket room. ## User Flow @@ -14,7 +14,7 @@ Live Share is the temporary Markdown collaboration feature in Markdown Viewer. I 8. The invite link includes the selected role and capability for the recipient. Participants open it, join a temporary live tab, request the current Yjs state, and render participant avatars/cursors. 9. The host can end the room for everyone. -The invite URL contains the room id, secret, and title. It does not embed the full Markdown document body. +The invite URL contains the room id, secret, title, selected role, and that role's bearer capability. It does not embed the full Markdown Document body. ## Cloudflare Runtime @@ -37,6 +37,7 @@ The Durable Object: - Accepts the WebSocket pair. - Authenticates the host capability when the room is first created and checks edit/view capabilities against the stored room credentials for later connections. +- Persists the raw host, edit, and view capability values plus `createdAt` in Durable Object storage under `live-room-auth-v1`. - Assigns a temporary socket participant id. - Relays only known message types: `hello`, `presence`, `sync-request`, `sync-state`, `y-update`, `review-sync-request`, `review-sync-state`, `review-update`, `leave`, and `session-end`. - Filters messages by role: viewers can send presence, sync requests, and Review updates but not Markdown updates or session-end; editors can send Markdown and Review updates; only the host can publish full Review state and every supported message type. @@ -70,15 +71,27 @@ Live Share relays: - Leave events. - Host session-end events. -Live Share does not write document content to Cloudflare KV or a database. State is temporary room/connection state in the Durable Object and clients. The normal local workspace remains local, and joined live tabs are temporary so they are not saved into the participant's tab storage. +Live Share does not write Markdown or Review Document content to Cloudflare KV or Durable Object storage. Those updates exist in connected clients and WebSocket relay traffic. The Durable Object does persist the role capability record described above. The normal local Workspace remains local, and joined live tabs are temporary so they are not saved into the participant's tab storage. + +## Room Lifecycle and Recovery + +- The host's client supplies the initial Yjs state to joining participants. +- If no active client can supply initial state, the participant times out after 8 seconds and sees an ended/expired/unavailable message. +- The server does not retain a Markdown or Review copy for recovery after all content-bearing clients leave. +- The host's **End session** action broadcasts `session-end` and disconnects active clients. +- Ending a session does not delete the Durable Object capability record. +- No application TTL, alarm, or deletion route is implemented for that capability record. + +“Expired room” in the client is therefore an availability message, not proof that all server-side capability metadata was deleted. ## Privacy and Security Notes - The room secret is part of the invite URL. Anyone with the link can try to join while the room is active. - No end-to-end encryption is implemented in the app. -- View-only and editable roles are checked by the Durable Object, which filters message types by capability. Each capability is still a bearer credential, so treat role-specific invite links as sensitive and do not paste them into public channels. +- View only and Can edit roles are checked by the Durable Object, which filters message types by capability. Each capability is still a bearer credential, so treat role-specific invite links as sensitive and do not paste them into public channels. - The server rejects unsupported WebSocket origins, but origin checks do not replace authentication or end-to-end encryption. -- The host should end the room when collaboration is finished. +- The host should end the room when collaboration is finished and every participant should export any copy they need before leaving. +- Capability metadata remains in Durable Object storage after the active session ends. - Cloudflare deployment logs and platform behavior are controlled by the deployer's Cloudflare account configuration. ## Required Configuration @@ -100,3 +113,5 @@ new_sqlite_classes = ["LiveRoom"] ``` Share Snapshot and managed media use separate key prefixes in `SHARE_KV`; Live Share uses `LIVE_ROOMS`. They should not be described as the same storage path. + +Related pages: [Share Snapshot](Share-Snapshot.md), [Privacy and Security](Privacy-and-Security.md), [Configuration](Configuration.md), and [Troubleshooting](Troubleshooting.md#live-share-fails-or-reports-an-expired-room). diff --git a/wiki/Localization.md b/wiki/Localization.md index 191a7f07..6d753927 100644 --- a/wiki/Localization.md +++ b/wiki/Localization.md @@ -2,6 +2,8 @@ Markdown Viewer translates its interface in the browser. Core labels live in `I18N_DICTS` in `script.js`, while broader static and dynamic interface strings are loaded from `assets/i18n/.json`. User-authored Markdown and filenames are never translated. +The English interface and English documentation are the source text. The approved multilingual terminology tables on this page align documentation with the current interface labels. + ## Supported Locales | Code | Language | @@ -21,6 +23,18 @@ Markdown Viewer translates its interface in the browser. Core labels live in `I1 | `tw` | Traditional Chinese | | `uk` | Ukrainian | +## Maintained Documentation Entry Points + +| Language | File | +| :--- | :--- | +| English | [`README.md`](../README.md) | +| Japanese | [`locales/README_ja.md`](../locales/README_ja.md) | +| Korean | [`locales/README_ko.md`](../locales/README_ko.md) | +| Simplified Chinese | [`locales/README_zh.md`](../locales/README_zh.md) | +| Traditional Chinese | [`locales/README_tw.md`](../locales/README_tw.md) | + +Detailed Wiki pages are maintained in English. Localized READMEs label those destinations as English instead of pointing to nonexistent localized pages. + ## Selection Order The app chooses a language in this order: @@ -66,7 +80,99 @@ The runtime also supports numbered templates such as `{{0}} files`. If a catalog - Keep all locale catalogs on the same key set as `en.json`. - Run the desktop prepare step so bundled catalogs match the web app. - Check desktop and mobile menus, context menus, modal buttons, validation messages, Share Snapshot, Live Share, and `?lang=` URLs. +- Update the terminology tables on this page when a named concept or interface label changes. +- For documentation, finalize `README.md` before synchronizing the four localized READMEs. +- Preserve code, commands, paths, URLs, routes, configuration keys, library names, Markdown syntax, and Git branch names. +- Verify localized language navigation, relative paths, anchors, tables, code fences, heading length, and native grammar. +- Record a section for native-speaker review when technical meaning cannot be translated confidently. + +## Terminology Glossary + +Use these terms in Markdown Viewer documentation and translation reviews. The Japanese, Korean, Simplified Chinese, and Traditional Chinese values follow the current interface label when that exact source key exists; otherwise they use standard software terminology for the concept. + +**Markdown Viewer** is a product name and must not be translated. Code, commands, file paths, URLs, API routes, configuration keys, library names, Markdown syntax, and Git branch names also remain unchanged. + +### Core Terms + +| English | Japanese | Korean | Simplified Chinese | Traditional Chinese | +| :--- | :--- | :--- | :--- | :--- | +| Workspace | ワークスペース | 작업공간 | 工作区 | 工作區 | +| Secret Workspace | 秘密のワークスペース | 비밀 작업 공간 | 秘密工作区 | 秘密工作區 | +| Folder | フォルダー | 폴더 | 文件夹 | 資料夾 | +| Document | 文書 | 문서 | 文档 | 文件 | +| Active Document | アクティブな文書 | 활성 문서 | 当前文档 | 目前文件 | +| Editor | エディター | 편집기 | 编辑器 | 編輯器 | +| Preview | プレビュー | 미리보기 | 预览 | 預覽 | +| Split view | 分割表示 | 분할 보기 | 分屏视图 | 分割檢視 | +| Review | レビュー | 리뷰 | 审阅 | 審閱 | +| Comment | コメント | 댓글 | 评论 | 留言 | +| Suggestion | 提案 | 제안 | 建议 | 建議 | +| Recent | 最近使ったファイル | 최근 파일 | 最近使用 | 最近使用 | +| Favorites | お気に入り | 즐겨찾기 | 收藏夹 | 我的最愛 | +| Local storage | ローカルストレージ | 로컬 저장소 | 本地存储 | 本機儲存空間 | +| Temporary tab | 一時タブ | 임시 탭 | 临时标签页 | 暫存分頁 | + +### Sharing, Privacy, and Access + +| English | Japanese | Korean | Simplified Chinese | Traditional Chinese | +| :--- | :--- | :--- | :--- | :--- | +| Share Snapshot | スナップショットの共有 | 스냅샷 공유 | 分享快照 | 分享快照 | +| Live Share | ライブシェア | 라이브 공유 | 实时共享 | 即時共享 | +| View only | 表示のみ | 보기 전용 | 仅供查看 | 僅供查看 | +| Can edit | 編集可能 | 편집 가능 | 可以编辑 | 可以編輯 | +| Host | ホスト | 호스트 | 主持人 | 主持人 | +| Editor role | 編集者ロール | 편집자 역할 | 编辑者角色 | 編輯者角色 | +| Viewer role | 閲覧者ロール | 뷰어 역할 | 查看者角色 | 檢視者角色 | +| Temporary room | 一時ルーム | 임시 방 | 临时房间 | 暫時房間 | +| Bearer link | ベアラーリンク | 베어러 링크 | 持有者链接 | 持有者連結 | +| Private mode | プライベートモード | 프라이빗 모드 | 隐私模式 | 隱私模式 | +| Clear local data | ローカルデータを消去 | 로컬 데이터 지우기 | 清除本地数据 | 清除本機資料 | +| Reset workspace | ワークスペースをリセット | 작업공간 재설정 | 重置工作区 | 重設工作區 | +| Managed media | 管理対象メディア | 관리형 미디어 | 托管媒体 | 受管理媒體 | +| Deletion token | 削除トークン | 삭제 토큰 | 删除令牌 | 刪除權杖 | +| Expiration | 有効期限 | 만료 | 过期 | 到期 | +| End-to-end encryption | エンドツーエンド暗号化 | 종단 간 암호화 | 端到端加密 | 端對端加密 | + +### Content, Import, and Export + +| English | Japanese | Korean | Simplified Chinese | Traditional Chinese | +| :--- | :--- | :--- | :--- | :--- | +| Import | インポート | 가져오기 | 导入 | 導入 | +| Export | エクスポート | 내보내기 | 导出 | 匯出 | +| Markdown export | Markdown エクスポート | Markdown 내보내기 | Markdown 导出 | Markdown 匯出 | +| HTML export | HTML エクスポート | HTML 내보내기 | HTML 导出 | HTML 匯出 | +| Browser Print | ブラウザー印刷 | 브라우저 인쇄 | 浏览器打印 | 瀏覽器列印 | +| Legacy Raster PDF | 従来のラスター PDF | 레거시 래스터 PDF | 旧版栅格 PDF | 舊版點陣 PDF | +| PNG export | PNG エクスポート | PNG 내보내기 | PNG 导出 | PNG 匯出 | +| Diagram | 図表 | 다이어그램 | 图表 | 圖表 | +| Diagram renderer | 図表レンダラー | 다이어그램 렌더러 | 图表渲染器 | 圖表轉譯器 | +| Remote renderer | リモートレンダラー | 원격 렌더러 | 远程渲染器 | 遠端轉譯器 | +| Sanitized HTML | サニタイズ済み HTML | 정제된 HTML | 已清理的 HTML | 已清理的 HTML | +| Code highlighting | コードのシンタックスハイライト | 코드 구문 강조 | 代码语法高亮 | 程式碼語法醒目提示 | +| Math | 数式 | 수식 | 数学公式 | 數學公式 | +| Progressive Web App (PWA) | プログレッシブウェブアプリ(PWA) | 프로그레시브 웹 앱(PWA) | 渐进式 Web 应用(PWA) | 漸進式 Web 應用程式(PWA) | +| Desktop application | デスクトップアプリケーション | 데스크톱 애플리케이션 | 桌面应用 | 桌面應用程式 | + +### Usage Rules + +- In English, keep the feature names **Share Snapshot**, **Live Share**, **View only**, **Can edit**, **Private mode**, and **Secret Workspace** exactly as written. +- In localized READMEs, use the localized UI label in explanatory prose. Keep the English feature name at first mention when it helps readers match English screenshots or Wiki pages. +- Do not alternate between “snapshot sharing,” “share link,” and **Share Snapshot** for the named feature. +- Use “live room” only for the technical room; use **Live Share** for the feature. +- Use “Document” for user content and “file” for an imported, exported, or filesystem object. +- Use “Workspace” for the product's document container and “repository” for GitHub source. +- Use “Preview” for the rendered pane and “renderer” for the library or service that creates visual output. +- Use “local-first” to describe the default data path. Do not use it to imply that every feature is offline or network-free. +- Use “temporary” only with the exact lifetime or persistence boundary nearby. + +### UI Alignment Notes + +- `assets/i18n/.json` is the current UI catalog source. Some concepts in these tables do not have a standalone source key and therefore cannot be compared one-to-one. +- The Traditional Chinese catalog currently uses `導入` for **Import**. Documentation uses that value when naming the UI action, even though `匯入` is also common in Traditional Chinese software. +- If a UI label changes, update the English catalog first, regenerate locale catalogs, review the change in context, then update these tables and affected localized documentation. ## Privacy Localization is local. The app does not send document text or UI text to machine translation APIs. + +Related pages: [Contributing](Contributing.md) and [Documentation Home](Home.md). diff --git a/wiki/Markdown-Reference.md b/wiki/Markdown-Reference.md index ecdf093d..69623593 100644 --- a/wiki/Markdown-Reference.md +++ b/wiki/Markdown-Reference.md @@ -4,6 +4,8 @@ Markdown Viewer supports standard Markdown, GitHub-Flavored Markdown (GFM), sele All rendered HTML is sanitized before display. Raw HTML is useful for formatting, but scripts and unsafe event handlers are removed. The preview is GitHub-style and GFM-oriented, not a promise of byte-for-byte identical rendering to GitHub, Pandoc, Obsidian, Typora, or other Markdown tools. +For editing workflows, see [Usage Guide](Usage-Guide.md). For renderer network and privacy boundaries, see [Privacy and Security](Privacy-and-Security.md). + ## Core Markdown and GFM ### Headings @@ -401,9 +403,32 @@ C D E F | G A B c | ABCJS renders sheet music. Playback uses browser audio support and shows a synchronized cursor and note highlighting when audio is supported. The toolbar can copy or export the rendered score as PNG or SVG. +## Official Renderer Documentation + +Use these upstream references for complete syntax and renderer-specific behavior: + +| Markdown Viewer feature | Official documentation | +| --- | --- | +| Mermaid | [Mermaid](https://mermaid.js.org/) | +| PlantUML | [PlantUML](https://plantuml.com/) | +| Remote diagram service | [Kroki](https://kroki.io/) | +| Graphviz/DOT | [Graphviz](https://graphviz.org/) | +| D2 | [D2](https://d2lang.com/) | +| Vega-Lite | [Vega-Lite](https://vega.github.io/vega-lite/) | +| WaveDrom | [WaveDrom](https://wavedrom.com/) | +| Markmap | [Markmap](https://markmap.js.org/) | +| GeoJSON and TopoJSON maps | [Leaflet](https://leafletjs.com/) and [TopoJSON](https://github.com/topojson/topojson) | +| STL | [Three.js](https://threejs.org/) | +| ABC notation | [ABCJS](https://www.abcjs.net/) | +| Math | [MathJax](https://www.mathjax.org/) | + +Upstream support does not imply that Markdown Viewer exposes every upstream option. The verified fence behavior and limits on this page describe the application. + ## Export Notes for Markdown Authors - Browser Print is usually best for long documents. - Raster PDF and PNG exports are screenshots of rendered HTML and can be affected by cross-origin images, very large canvases, and late-loading remote diagrams. - Remote-rendered diagrams should finish rendering before export. - Wide tables, large diagrams, and huge STL models may be scaled or moved during export. + +Related pages: [Features](Features.md), [Usage Guide](Usage-Guide.md), and [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Privacy-and-Security.md b/wiki/Privacy-and-Security.md new file mode 100644 index 00000000..5c9c0115 --- /dev/null +++ b/wiki/Privacy-and-Security.md @@ -0,0 +1,185 @@ +# Privacy and Security + +Markdown Viewer is local-first: normal editing, Preview rendering, local file import, Workspace organization, and most exports run on the device. It is not network-free. This page is the authoritative user-facing description of local storage, network features, retention, bearer links, content sanitization, deployment protections, and known security limitations. + +## Privacy Summary + +- No account or login is required. +- The application code does not implement analytics, telemetry, advertising, tracking pixels, or app-specific cookies. +- Normal documents are stored in browser `localStorage`; the desktop application mirrors selected values into Neutralino storage. +- Private mode disables document-state persistence after clearing existing persisted document state. +- Secret Workspace encrypts its stored files and folder names on the device. +- Network-backed features send only the data needed for that feature, but the receiving service or deployment platform can log requests according to its own policy. +- Share Snapshot and Live Share URLs are bearer links. Possession of a valid link grants the capability encoded in it. +- Live Share is not end-to-end encrypted. + +> **Privacy:** Do not place sensitive Markdown in a remote-rendered diagram, managed-media upload, stored Share Snapshot, or Live Share room unless you accept the stated service and bearer-link boundaries. + +## Data Stored on the Device + +| Data | Web location | Desktop behavior | +| :--- | :--- | :--- | +| Normal Workspace documents and review threads | `markdownViewerTabs` in `localStorage` | Mirrored to Neutralino storage | +| Folder and Workspace organization | `markdownViewerDocumentOrganization` | Mirrored | +| Encrypted Secret Workspace payload | `markdownViewerSecretWorkspace` | Mirrored | +| Active document and untitled counter | `markdownViewerActiveTab`, `markdownViewerUntitledCounter` | Mirrored | +| Theme, direction, view, and related preferences | `markdownViewerGlobalState` | Mirrored | +| Interface language | `app-lang` | Local browser value; restored in prepared desktop use where available | +| Find and Replace docking preference | `find-replace-docked` | Local browser value; restored in prepared desktop use where available | +| Private mode preference | `markdownViewerPrivateMode` | Remains locally so the mode survives reload | + +Temporary Share Snapshot and Live Share participant tabs are removed before normal tab persistence. Opening someone else's link therefore does not silently add that temporary document to the saved Workspace. + +Browser storage quotas and user-cleared site data still apply. The application cannot recover data after the browser, operating system, user, or storage policy deletes it. + +## Private Mode, Reset Workspace, and Secret Workspace + +These controls have different purposes: + +| Control | Effect | Important limitation | +| :--- | :--- | :--- | +| **Private mode** | Clears persisted document-state keys and blocks further writes while enabled | It also clears the persisted encrypted Secret Workspace payload. Current in-memory work can continue for the session, but it will not survive reload or exit. | +| **Reset workspace** | Ends Live Share, removes normal documents and review data, deletes Secret Workspace storage, and restores the welcome document | The deleted content cannot be recovered by Markdown Viewer. | +| **Reset Secret Workspace** | Deletes every encrypted Secret Workspace file and folder | Irreversible; a confirmation is shown. | +| Lock Secret Workspace | Removes the in-memory key and hides encrypted content | The encrypted payload remains stored locally. | + +> **Warning:** Export any document you need before enabling Private mode or selecting **Reset workspace**. Both paths remove persisted Secret Workspace data in the current implementation. + +Secret Workspace uses PBKDF2 with SHA-256, 250,000 iterations, a random salt, and AES-GCM with a 256-bit derived key. The key remains in memory only while the Workspace is unlocked. File contents and folder names are encrypted; item counts, salt, initialization vector, iteration count, and format version remain outside the ciphertext as metadata. A forgotten password cannot be recovered. + +Secret Workspace protects the stored payload from casual inspection at rest. It does not protect content after you unlock it, export it, send it through a network feature, or expose the running device or browser session. + +### Clear Local Data + +Export needed Documents first. Use **Reset workspace** to remove the application's normal Document, review, Folder, and Secret Workspace state. Clearing site data in the browser also removes Markdown Viewer `localStorage`, preferences, the Service Worker, and cached assets for that origin. Browser-level clearing cannot be undone by Markdown Viewer. + +In the desktop application, use the in-application reset controls for known Markdown Viewer values. Removing application storage through the operating system or uninstall process can delete local data according to that platform's behavior. + +## Data That Can Leave the Device + +| Feature | Data sent | Destination and retention | Access model | +| :--- | :--- | :--- | :--- | +| Web/PWA library loading | Library requests, IP and normal HTTP metadata | cdnjs, jsDelivr, or esm.sh; browser/Service Worker cache | Governed by the remote host | +| GitHub import | Repository/path request and selected public content downloads | GitHub API and `raw.githubusercontent.com` | Public repositories only; no token flow | +| Emoji lookup | Emoji API request | GitHub API; response kept in memory/cache | Remote host | +| Remote diagrams | Diagram source or encoded source | PlantUML, Kroki, or mermaid.ink; response can be browser-cached | Remote renderer receives the source | +| GeoJSON/TopoJSON maps | Tile and external-asset requests | Configured map-tile or asset host | Remote host | +| External Markdown assets | Image, media, font, and link requests | Author-specified host | Remote host | +| Managed media | Optimized image, GIF, or video after first-use consent | Cloudflare KV for 90 days from the latest upload of identical content | Public to anyone with the unguessable URL | +| Stored Share Snapshot | Markdown content, mode, title, creation time, and size | Cloudflare KV for 90 days | Bearer snapshot URL | +| Live Share | Yjs Markdown/Review updates, display name, presence, cursor, sync, leave, and session-end messages | Cloudflare Durable Object relay while clients are connected | Room secret plus host/edit/view capability | +| Live Share capability metadata | Host, edit, and view bearer capability values plus `createdAt` | Durable Object storage; no application TTL or deletion path is implemented | Used by the Durable Object to authenticate roles | + +Cloudflare, CDN, GitHub, renderer, map, external-asset, reverse-proxy, and self-hosting operators can retain normal service logs independently of Markdown Viewer's application-level storage. + +## Managed Media + +Supported managed media includes AVIF, BMP, GIF, JPEG, PNG, WebP, MP4, WebM, and Ogg. The client asks for consent before its first managed upload. + +- Source files are limited to 25 MiB before processing. +- Stored still images are limited to 300 KiB after optimization. +- Stored GIFs are limited to 5 MiB. +- Stored videos are limited to 10 MiB. +- The API validates declared media type and file signature. +- The content-derived URL is difficult to guess but is not an authorization mechanism. +- Uploading identical content reuses its identifier and refreshes the 90-day expiry. +- Share Snapshot and Live Share include the URL in Markdown; they do not make a second media copy. +- After expiry, the Markdown reference remains but the media stops loading. + +There is no user deletion token for managed media. Expiry is the implemented removal mechanism. + +## Share Snapshot + +Small Share Snapshot content remains in the URL hash as `#share=...`. A hash fragment is not included in the normal HTTP request to open the page, although it can be exposed when a user copies the URL into another system, browser history is synchronized, extensions inspect the page, or the page itself processes the hash. + +Stored snapshots use `#id=...` and Cloudflare KV. They expire after 90 days. The Share API returns a deletion token to the creating client and stores only its hash. The current application UI does not display the token or offer an early-delete control; an API client must capture the creation response and call `DELETE /api/share/` with that token. + +View only prevents normal editing in the client. Can edit lets the recipient change their temporary local copy. Neither mode is an authentication boundary, and Can edit snapshots are not real-time collaboration. + +See [Share Snapshot](Share-Snapshot.md). + +## Live Share + +The Live Share relay does not persist Markdown or Review document state to KV or Durable Object storage. It does persist the host/edit/view capability record and `createdAt` in Durable Object storage so sockets can be authenticated. + +- Hosts, editors, and viewers use distinct bearer capabilities. +- The server filters supported message types by role. +- Viewers cannot send Markdown updates or end the session; they can send presence, sync requests, and Review updates. +- The room secret and selected role capability are included in the invite URL. +- Anyone with a valid invite can attempt to join while a host is available. +- There is no end-to-end encryption. +- Ending a session broadcasts a client event and disconnects participants; it does not delete the stored capability record. +- No application TTL, explicit capability-record deletion, or server-side document history is implemented. + +See [Live Share](Live-Share-Cloudflare.md). + +## Content Sanitization + +Markdown is parsed with Marked, then rendered HTML is sanitized with DOMPurify before insertion into Preview. The allowlist includes the elements and attributes needed for math, task lists, media, renderer metadata, and accessibility. Scripts, inline event handlers, unsafe URI schemes, and SVG data URLs are not preserved. + +Remote SVG diagrams receive additional processing: scripts and `foreignObject` elements are removed, unsafe attributes are stripped, and the result is sanitized before use. + +Sanitization reduces cross-site scripting risk. It is not a guarantee against browser defects, third-party library vulnerabilities, malicious external resources, or unsafe changes to the sanitizer configuration. + +## Export Security + +- Markdown export writes the raw source. +- HTML export uses sanitized content, a restrictive Content Security Policy (CSP), and Subresource Integrity (SRI) metadata where external assets have known hashes. +- Browser Print delegates final output to the browser or operating system. +- Legacy raster PDF and PNG use `html2canvas` with `allowTaint: false` and CORS-aware fetching. +- An exported HTML file can still request external images, media, fonts, or renderer libraries that the document references and the CSP permits. + +Inspect sensitive documents and their external URLs before distributing an exported file. + +## Deployment Protections + +Cloudflare Pages uses the checked-in `_headers` and `_redirects` files for: + +- CSP; +- HSTS; +- clickjacking protection; +- MIME-sniffing protection; +- referrer and permissions policies; +- cross-origin opener/resource policies; and +- 404 responses for selected sensitive or source-map paths. + +The stock Docker image defines its own Nginx CSP and security headers. It is not identical to the Cloudflare policy. Self-hosters are responsible for TLS, logs, updates, headers, reverse-proxy behavior, compatible endpoint configuration, and retention in any replacement storage service. + +Origin allowlists on Share and Live Share endpoints reduce unauthorized browser-origin use. They do not make bearer URLs secret and do not replace authentication, authorization, or encryption. + +## Desktop Native API Restrictions + +The default Neutralino configuration enables only: + +- app exit; +- open/save dialogs and message boxes; +- external URL opening and tray setup; +- file read/write; and +- storage get/set. + +`os.execCommand` is not in the default allowlist. The standard desktop application therefore cannot execute PlantUML or D2 command-line programs through the local-renderer code path. PlantUML and D2 use remote services in the standard build. A custom build that enables command execution changes the threat model and must use explicit user consent and narrowly fixed commands. + +## Security Reporting + +Do not publish vulnerability details in a normal issue. Use GitHub's private security-reporting channel when it is available for this repository, or contact the maintainers privately with: + +- the affected version or commit; +- a minimal reproduction; +- security impact; +- required preconditions; and +- suggested mitigation, if known. + +See [Contributing: Security Reports](Contributing.md#security-reports). + +## Known Limitations + +- Bearer links can be forwarded, logged by surrounding systems, copied into chat, or exposed through browser synchronization. +- Live Share is not end-to-end encrypted and persists capability metadata without an application TTL. +- The current Share Snapshot UI does not expose the early-deletion token. +- Managed media has no early-delete control. +- Private mode and Reset workspace delete persisted Secret Workspace data. +- Security headers differ by deployment target and can be weakened by self-hosting changes. +- Remote services and external assets operate under their own privacy, availability, and logging policies. +- Browser storage, extensions, malware, a compromised device, and users with local profile access remain outside the application's protection boundary. + +Related pages: [Features](Features.md), [Configuration](Configuration.md), [Share Snapshot](Share-Snapshot.md), [Live Share](Live-Share-Cloudflare.md), and [Troubleshooting](Troubleshooting.md). diff --git a/wiki/Share-Snapshot.md b/wiki/Share-Snapshot.md new file mode 100644 index 00000000..f63dc7de --- /dev/null +++ b/wiki/Share-Snapshot.md @@ -0,0 +1,124 @@ +# Share Snapshot + +Share Snapshot creates a point-in-time copy of the active Document. Use it when a recipient needs to read or edit a copy without joining a Live Share room. + +Share Snapshot is not real-time collaboration. Changes made by the sender or recipient after link creation do not synchronize. + +## Create a Snapshot + +1. Open the Document you want to share. +2. Select **Share Snapshot**. +3. Choose **View only** or **Can edit**. +4. Select **Share**. +5. Copy the generated URL and send it through a channel you trust. + +The application selects URL-hash or Cloudflare KV storage automatically according to content size and encoded URL length. + +> **Privacy:** A Share Snapshot is a bearer link. Anyone who obtains the complete URL can open the capability it contains. There is no account check or recipient allowlist. + +## Access Modes + +| Mode | Recipient experience | What it does not provide | +| :--- | :--- | :--- | +| **View only** | Opens a temporary tab in Preview with editing actions blocked | Authentication, access revocation, or protection against link forwarding | +| **Can edit** | Opens a temporary tab in Split view and lets the recipient edit that local copy | Real-time synchronization or write access to the sender's original Document | + +The recipient's temporary snapshot tab is not written into normal Workspace tab storage. Closing or reloading can discard edits unless the recipient exports the Markdown. + +The application blocks creating another Share Snapshot from a temporary snapshot. Only the host can create a snapshot from a Live Share Document. + +## Storage Modes + +| Property | URL-hash snapshot | Stored snapshot | +| :--- | :--- | :--- | +| URL form | `#share=` | `#id=` | +| Selection rule | Used when Markdown is below 3,000 UTF-8 bytes and the encoded URL is no longer than 4,096 characters | Used at 3,000 bytes or more, or when the encoded URL exceeds 4,096 characters | +| Content location | Compressed and base64url-encoded inside the link | Cloudflare KV through `/api/share` | +| Retention | No server-side record created by Markdown Viewer; the copied URL itself remains usable | 90 days | +| Maximum content | Constrained by practical browser, clipboard, and URL handling | 8,000,000 characters | +| Early deletion | Delete every copy of the link that you control | Available through the API only when the caller retained the creation deletion token | +| Server request when opening | The URL hash is not part of the normal HTTP request; the page processes it locally | The application requests `/api/share/` | + +The URL-hash title and access flag are also stored in the fragment. Hash fragments can still be exposed through copied messages, browser synchronization/history, extensions, screenshots, logs from surrounding tools, or a person who forwards the URL. + +## Stored Snapshot Record + +The Share API stores: + +- Markdown content; +- access mode; +- sanitized title; +- creation time; +- character count; and +- a hash of the deletion token. + +The record is written to `SHARE_KV` with a 90-day time to live. The API response uses `Cache-Control: no-store`. + +Creating a stored snapshot returns: + +- a random snapshot id; +- a deletion token; and +- the expiry duration. + +The deletion token is returned only at creation. The stored record contains its SHA-256 hash, not the original token. + +## Delete a Stored Snapshot + +The API supports: + +```http +DELETE /api/share/ +Content-Type: application/json + +{"deleteToken":""} +``` + +> **Important:** The current Markdown Viewer UI does not display or export the deletion token and does not provide a Delete snapshot action. It keeps the token only in page memory while the generated link state exists. Closing/resetting the modal or leaving the session loses normal UI access to it. + +An API client that needs early deletion must call `POST /api/share`, securely capture the `deleteToken` from the response, keep it separate from the shared URL, and later submit it to the `DELETE` route. Without the token, wait for the 90-day expiry. + +Deleting a snapshot does not delete managed images, GIFs, or videos referenced by the Markdown. Managed media has separate content-addressed records and its own 90-day expiry. + +## Images and Other External Content + +Share Snapshot copies Markdown, not every referenced resource. + +- Managed media remains available through its public-by-link URL until that media record expires. +- External images, media, fonts, and links are requested from their original hosts. +- Legacy inline data images increase the snapshot size and can force stored-snapshot mode. +- Review comments and suggestions are not included. +- A remote diagram fence is re-rendered by the recipient's browser and can send its source to a renderer. + +## Security Boundaries + +- Snapshot ids and encoded content are difficult to guess but are not authentication. +- View only is enforced by the client interface; it does not encrypt or hide the Markdown from someone who controls their browser. +- Origin checks restrict supported browser origins for API creation and access, but requests without an `Origin` header are accepted and bearer-link secrecy remains essential. +- Allowed application origins include the production site, HTTPS `*.markdownviewer.pages.dev` previews, `null`, and local `localhost`/`127.0.0.1` development origins. +- Stored snapshots are not end-to-end encrypted by the application. +- Cloudflare and the deployer can process normal platform and request logs. + +Do not use Share Snapshot as a confidential-document access-control system. + +## Failure and Recovery + +| Symptom | Likely cause | Action | +| :--- | :--- | :--- | +| “Failed to create share link” | Pako or `/api/share` unavailable, missing `SHARE_KV`, disallowed origin, network error, or oversized content | Check the console/network request, configuration, origin, and 8,000,000-character limit | +| Stored link returns not found | Invalid id, early deletion, or 90-day expiry | Ask the sender for a new snapshot | +| Can edit copy disappeared | Snapshot tabs are temporary | Export Markdown before closing or reloading | +| Image is missing | Managed-media expiry, unavailable external host, or blocked request | Replace the resource and create a new snapshot | +| Remote diagram is missing | Renderer unavailable, CSP restriction, or invalid source | Check the renderer network request and fence syntax | + +See [Troubleshooting](Troubleshooting.md) for broader diagnostics. + +## API Summary + +| Method and route | Purpose | +| :--- | :--- | +| `POST /api/share` | Create a stored snapshot | +| `GET /api/share/` | Load a stored snapshot | +| `DELETE /api/share/` | Delete a stored snapshot with its deletion token | +| `OPTIONS /api/share[/]` | CORS preflight | + +Deployment details are in [Configuration](Configuration.md#share-api). For the product-wide data boundary, see [Privacy and Security](Privacy-and-Security.md). diff --git a/wiki/Troubleshooting.md b/wiki/Troubleshooting.md new file mode 100644 index 00000000..2e5c2acd --- /dev/null +++ b/wiki/Troubleshooting.md @@ -0,0 +1,262 @@ +# Troubleshooting + +Use this page to diagnose Markdown Viewer setup, Preview, import, renderer, export, sharing, storage, and desktop problems. Start with the symptom, check the likely causes in order, and avoid clearing site data until you have exported any Document you need. + +## Before You Start + +1. Export important Documents as Markdown. +2. Record the application version from **About Markdown Viewer**. +3. Record the delivery target: hosted web app, PWA, local static server, Docker, Cloudflare deployment, or desktop application. +4. Open the browser developer console and Network panel when available. +5. Reproduce the problem with a small Document that does not contain confidential data. + +When reporting a bug, include the smallest safe reproduction, browser or operating system, delivery target, expected result, actual result, and relevant console/network errors. + +## The Application Does Not Load + +### You opened `index.html` with `file://` + +Serve the repository over HTTP: + +```bash +python -m http.server 8080 +``` + +Open `http://localhost:8080`. Web Workers and Service Workers can be blocked under `file://`. + +### The page is blank or scripts are blocked + +- Confirm that JavaScript is enabled. +- Check the console for CSP, SRI, MIME-type, or network failures. +- Confirm that `index.html`, `script.js`, `styles.css`, `preview-worker.js`, `sw.js`, `manifest.json`, `sample.md`, and `assets/` are served at the expected paths. +- If self-hosting under a sub-path, verify Worker, Service Worker, manifest, asset, and dynamic-library URLs. +- Hard-refresh once to bypass a stale page shell. + +Do not weaken CSP to `*` as a first response. Add only the specific origins required by the deployed features. + +## The Preview Is Blank or Stale + +- Check that Marked, Highlight.js, and DOMPurify loaded successfully. +- Look for a DOMPurify error. Secure rendering aborts if the sanitizer is unavailable. +- Confirm that the Document is the active tab and that Preview is visible. +- For a large Document, wait for the worker timeout/fallback and check for `preview-worker.js` 404 errors. +- Try a minimal Document such as: + + ```markdown + # Preview check + + Plain text. + ``` + +- If the minimal Document works, reintroduce custom HTML, references, footnotes, and rich fences in small groups. + +Large Documents above 50,000 characters can use the Preview Worker when their structure is safe for segmented rendering. If the Worker fails repeatedly, the application falls back to main-thread rendering; typing can be less responsive. + +## Docker Preview or PWA Offline Support Is Incomplete + +The checked-in root `Dockerfile` does not copy `preview-worker.js` or `sample.md`, but `sw.js` includes both in its critical precache. In the stock image: + +- large-document Preview can fall back to the main thread after the Worker request fails; and +- Service Worker installation can fail because `cache.addAll()` requires every critical asset. + +This is a known product packaging limitation at the audited commit. A documentation-only change does not modify the image. + +For a custom image, serve every file in the [Installation: Static Hosting](Installation.md#static-hosting) list and verify that each Service Worker critical asset returns `200` with the correct MIME type. + +## A Local Markdown File Will Not Import + +Check: + +- the extension is `.md` or `.markdown`, or the file type is `text/markdown`; +- the file is no larger than 10 MB; +- the first 8 KiB does not contain a null byte, which makes the file look binary; +- the 50-Document Workspace limit has not been reached; and +- the browser or desktop application has permission to read the selected file. + +Extension matching is case-insensitive. Rename a plain-text file to `.md` only when it is actually Markdown text. + +## GitHub Import Fails or Shows Too Few Files + +- Use a public `github.com` repository, tree, blob, or `raw.githubusercontent.com` Markdown URL. +- Private repositories are unsupported because Markdown Viewer does not request a token. +- Repository and folder results show only the first 30 Markdown files. +- Check GitHub API rate-limit and network responses. +- Confirm that CSP allows `api.github.com` and `raw.githubusercontent.com`. +- For a direct file, verify that the URL returns text rather than a login or HTML error page. + +## Media Upload Fails + +Check the format and size: + +| Media | Limit | +| :--- | ---: | +| Source file before client processing | 25 MiB | +| Optimized still image | 300 KiB | +| GIF | 5 MiB | +| MP4, WebM, or Ogg video | 10 MiB | + +Then check: + +- first-use consent was accepted; +- `SHARE_KV` is configured; +- the request origin is allowed; +- the file signature matches its declared MIME type; +- `/api/image` or `/api/media` is reachable; and +- CSP permits the production API. + +An expired managed-media URL returns not found after 90 days. Create a new upload and update the Markdown reference. + +## Math Does Not Render + +- Verify the LaTeX delimiters and escape a literal dollar sign as `\$`. +- Check whether MathJax loaded from the CDN or prepared desktop library. +- On first web use, confirm network access; later use can rely on the browser/Service Worker cache. +- Test with: + + ```markdown + Inline: $E = mc^2$ + + $$ + \sum_{i=1}^{n} i = \frac{n(n+1)}{2} + $$ + ``` + +- Check the console for MathJax parsing or loading errors. + +## A Diagram Does Not Render + +1. Confirm the fence name and source syntax in [Markdown Reference](Markdown-Reference.md). +2. Identify the rendering path: + + - Mermaid, Markmap, maps, STL, ABC, and math use client-side libraries. + - PlantUML uses the PlantUML server, with Kroki as a fallback. + - D2, Graphviz/DOT, Vega-Lite, and WaveDrom use Kroki. + - Some insertion previews use mermaid.ink or Kroki. + +3. Check CSP and network access to the required renderer. +4. Wait for the 15-second request timeout and retries. +5. Try the same source in a minimal Document. +6. Do not paste confidential source into a third-party renderer during diagnosis. + +The standard desktop configuration does not allow `os.execCommand`; local PlantUML/D2 command execution is therefore unavailable unless a custom build changes the native permissions and explicit opt-in. + +## A Map, STL Model, or ABC Score Fails + +### GeoJSON or TopoJSON + +- Validate the JSON. +- Check Leaflet and TopoJSON library loading. +- Check map-tile network requests and CSP. +- Remember that the geometry can render while background tiles remain unavailable. + +### STL + +- Keep source below 2 MiB. +- Ensure every parsed vertex is finite. +- Keep geometry at or below 300,000 vertices. +- Verify WebGL/GPU availability. +- Try a small ASCII STL to separate source and GPU problems. + +### ABC notation + +- Validate the ABC header and bar syntax. +- Confirm ABCJS loaded. +- Browser audio requires a supported AudioContext and often a user gesture. +- Check soundfont/network requests when playback, but not notation, fails. + +## PDF or PNG Export Is Missing Content + +- Wait for math, diagrams, maps, models, images, and fonts to finish rendering. +- Use Browser Print for most long, text-heavy Documents. +- Use Legacy Raster PDF only when screenshot-style pagination is needed. +- Check external images for CORS support; cross-origin images can be omitted from canvas exports. +- Reduce Document length, image dimensions, or renderer size if the browser reaches canvas or memory limits. +- Close other memory-heavy tabs. +- Check whether author-specified dark SVG, image, HTML, or diagram colors remain dark in Browser Print; the print path does not rewrite authored colors. + +The final print layout is controlled by the browser or operating system. Different engines can paginate differently. + +## Share Snapshot Fails + +- Confirm that Pako loaded. +- For stored mode, verify `/api/share`, `SHARE_KV`, request origin, and network access. +- Keep stored content at or below 8,000,000 characters. +- A not-found stored link is invalid, deleted, or expired after 90 days. +- A snapshot tab is temporary. Export Markdown before closing or reloading if you edited it. +- The current UI cannot delete a stored snapshot early because it does not expose the API deletion token. + +See [Share Snapshot](Share-Snapshot.md). + +## Live Share Fails or Reports an Expired Room + +- Ask the host to keep the room and original host Document open. +- Confirm the complete invite URL, including room secret, role, and capability. +- Verify that `/live-room/` upgrades to WebSocket. +- Check `LIVE_ROOMS`, Worker deployment, Durable Object migration, and allowed Origin. +- Join within the 8-second initial-state window. +- A room allows at most 64 WebSocket participants and 8 MB per message. +- Ask the host to start a new session if the room has ended or no host is available to provide initial state. + +The Durable Object persists role capability metadata but not Markdown or Review content. A participant cannot recover a Document from the server after every client with the content has left. + +See [Live Share](Live-Share-Cloudflare.md). + +## Documents Disappeared After Private Mode or Reset + +Private mode clears persisted document-state keys when enabled, including the encrypted Secret Workspace payload, then blocks further document-state writes. **Reset workspace** also deletes normal and Secret Workspace data before restoring the welcome Document. + +Markdown Viewer has no recovery mechanism for those deleted values. Check: + +- a previously exported `.md` file; +- browser/profile backups; +- operating-system backups for the desktop profile; or +- a Share Snapshot that has not expired. + +Do not clear site data or reinstall the desktop application while investigating storage loss. + +## Secret Workspace Will Not Unlock + +- Use the exact password created on that device/profile. +- Confirm that Web Crypto is available and the page uses a secure context. +- Do not reset the Secret Workspace unless you accept permanent deletion. +- A forgotten password cannot be recovered. +- Corrupt or partially cleared encrypted metadata cannot be reconstructed by the application. + +Secret Workspace data is local to the browser profile or desktop storage. It does not synchronize automatically across devices. + +## The PWA Is Not Available Offline + +- Service Workers require HTTPS or localhost. +- Confirm that `sw.js` registered and activated. +- Inspect the `markdown-viewer-cache-*` cache. +- Every critical asset must load successfully during installation. +- CDN libraries are cached only after their first successful request. +- Managed media, GitHub import, stored Share Snapshot, Live Share, remote diagrams, external assets, and map tiles still require the network. + +Clearing site data removes both the cache and locally saved Documents for that origin. + +## The Desktop Application Does Not Start + +- Run `npm install` and allow setup to download Neutralino binaries and libraries. +- Confirm that preparation generated `desktop-app/resources/libs/`. +- On Windows, review SmartScreen only if you trust the downloaded binary. +- On Linux, add execute permission. +- On macOS, use the documented quarantine command only if you trust the binary. +- Check that the executable matches the operating system and architecture. +- Re-run `npm run build` when prepared resources and root source are out of sync. + +See [Desktop Application](Desktop-App.md). + +## Report an Issue + +Search [existing issues](https://github.com/ThisIs-Developer/Markdown-Viewer/issues) first. If the problem is new, include: + +- version or commit; +- browser/OS and delivery target; +- exact reproduction steps; +- minimal non-sensitive Markdown; +- expected and actual result; +- console/network errors; and +- screenshots only when they add information not present in text. + +Do not attach confidential Documents, bearer links, deletion tokens, room secrets, or vulnerability details. Follow [Contributing](Contributing.md#security-reports) for security reports. diff --git a/wiki/Usage-Guide.md b/wiki/Usage-Guide.md index e49c35a7..993f5150 100644 --- a/wiki/Usage-Guide.md +++ b/wiki/Usage-Guide.md @@ -1,6 +1,6 @@ # Usage Guide: Online Markdown Editor with Live Preview -This guide explains how to use Markdown Viewer as a browser-based Markdown editor, viewer, reader, and live preview tool. For deeper implementation notes, privacy details, and renderer limits, see [Features](Features). +This guide explains how to use Markdown Viewer as a browser-based Markdown editor, viewer, reader, and live Preview tool. For deeper implementation notes and renderer limits, see [Features](Features.md). For data handling, see [Privacy and Security](Privacy-and-Security.md). ## Workspace Layout for Editing and Previewing Markdown @@ -28,6 +28,7 @@ To compare or edit two files, open a file menu and choose **Open in split view** - Drag a file row onto a folder or workspace to move it. Use **Move to…** from the file menu as the keyboard and touch-friendly alternative. Dropping local Markdown files onto a folder imports them there. - Use **All files** for the hierarchy, **Recent** for recently opened or edited files, and **Favorites** for starred files. - On desktop, one click selects a sidebar document and a double click opens it. On touch layouts, one tap opens it and closes the drawer. +- The active Document is the one shown in the primary Editor/Preview, used by formatting, review, import-into-current, export, Share Snapshot, and Live Share actions. Opening a second Document in the two-Document view does not make it the active Document. - Each document menu supports Open, Rename, Duplicate, Favorites, Move, Open in split view, Download Markdown, and Delete. The tab strip supports quick switching, drag-to-reorder, and close commands for one or several tabs. - Ctrl/Cmd-click selects separate Explorer items; Shift-click or Shift+Arrow selects a range. When only files are selected, the context menu can **Open all** or **Move to…**. Any multi-selection can be deleted after confirmation. - Deleting a folder tree moves all files inside it to the workspace root before removing the folders. @@ -36,11 +37,13 @@ To compare or edit two files, open a file menu and choose **Open in split view** - Normal tabs autosave to local browser storage or desktop storage. - The document limit is 50 stored files across creation, duplication, imports, Share Snapshot, Live Share joins, and locked Secret Workspace files. - Temporary Share Snapshot and Live Share tabs are not saved to the recipient's workspace. -- Use **Private mode** from Workspace settings to clear existing document state and prevent normal document-state persistence while it is enabled. -- Use **Reset workspace** from Workspace settings to remove saved files and review data and return to a clean workspace. +- Use **Private mode** from Workspace settings to clear existing Document state and prevent normal Document-state persistence while it is enabled. This also removes persisted Secret Workspace data. +- Use **Reset workspace** from Workspace settings to remove normal files, review data, and Secret Workspace storage, end Live Share, and return to a clean Workspace. - Right-click blank Explorer space to create a file or folder. Right-click the empty Quick Start area to open its five actions. Right-click an editor or preview to use the relevant clipboard and document commands. -Storage is local unless you explicitly use a network feature such as GitHub import, Share Snapshot storage, or Live Share. +> **Warning:** Export needed Documents before enabling Private mode or selecting **Reset workspace**. Markdown Viewer cannot recover deleted storage. + +Normal Workspace storage is local. Managed media, GitHub import, remote renderers, stored Share Snapshot, Live Share, external assets, map tiles, and uncached web libraries use the network. ## Editing Tools @@ -99,6 +102,7 @@ Paste an image or GIF from the clipboard, drop an image/GIF/video file, or use t - Managed still images are limited to 300 KiB after optimization. - Animated GIFs are limited to 5 MiB, and managed videos to 10 MiB. - Supported file types are `.md`, `.markdown`, and `text/markdown`. +- An individual local Markdown file is limited to 10 MB. - Extension matching is case-insensitive. - Dragging over the app shows a compact notice without blocking the editor or Explorer drop targets. - The app scans the first 8 KB for null bytes and rejects likely binary files. @@ -136,13 +140,15 @@ Raster PDF and PNG exports render Mermaid, ABC, and MathJax in an off-screen cap Use Share Snapshot when you want to send a point-in-time copy. -1. Choose View only or Editable. +1. Choose View only or Can edit. 2. Click Share. 3. Copy the generated link. -View only opens the document in preview mode and hides editing. Editable opens the copy in split mode so the recipient can edit their own local copy. It is not real-time collaboration. +View only opens the Document in Preview and hides editing. Can edit opens the copy in Split view so the recipient can edit their own local copy. It is not real-time collaboration. + +Small Documents are compressed into the URL hash as `#share=...`. Documents of at least 3,000 UTF-8 bytes, or whose encoded URL exceeds 4,096 characters, are stored through `/api/share` and opened with `#id=...`. Stored snapshots use Cloudflare KV for up to 90 days and can contain up to 8,000,000 characters. They are bearer links: anyone with the URL can open the snapshot. -Small documents are compressed into the URL hash as `#share=...`. Large documents, or documents whose encoded URL would be too long, are stored through `/api/share` and opened with `#id=...`. Stored snapshots use Cloudflare KV for up to 90 days and can contain up to 8,000,000 characters, including optimized images embedded in the Markdown. They are bearer links: anyone with the URL can open the snapshot. The creator-side API response includes a deletion token; keep it separate from the share URL if you need to delete the stored record before expiry. +The creation API returns a deletion token, but the current UI does not display it or provide an early-delete action. Normal UI-created stored snapshots therefore remain until expiry. See [Share Snapshot](Share-Snapshot.md). Shared snapshot tabs are temporary and are not saved into the recipient's workspace. @@ -156,7 +162,7 @@ Use Live Share when you want a temporary real-time room. 4. Start the session. 5. Copy the invite link after the room starts. -Live Share sends real-time Yjs updates through a Cloudflare Durable Object. It does not store the document in KV or a database. The invite URL contains a room id, room secret, access role/capability, and title, not the full document body. The server authenticates host, editable, and view-only capabilities and filters message types by role. Markdown and Review data use separate Yjs documents, so view-only participants can synchronize comments and suggestions without being allowed to edit Markdown. +Live Share sends real-time Yjs updates through a Cloudflare Durable Object. It does not persist Markdown or Review Document content server-side. The Durable Object does persist the host, edit, and view capability values plus their creation time. The invite URL contains a room id, room secret, access role/capability, and title, not the full Document body. The server authenticates host, Can edit, and View only capabilities and filters message types by role. Markdown and Review data use separate Yjs documents, so View only participants can synchronize comments and suggestions without being allowed to edit Markdown. Participants get a temporary live tab, presence avatars, and live cursor indicators. The host can end the session for everyone. Rooms are limited to 64 WebSocket participants and 8 MB live messages. Managed images, GIFs, and videos travel as short HTTPS links rather than binary Live Share messages and stop rendering when their 90-day storage TTL expires. @@ -191,3 +197,5 @@ Mermaid, Markmap, maps, STL, ABC, and MathJax use client-side libraries. PlantUM | Close modals, panels, tab menus, and diagram modals | `Escape` | Browser shortcuts are intentionally not all intercepted on the web. For example, web tab creation/closing uses `Alt+Shift+T/W` so the app does not hijack browser tab shortcuts. + +Related pages: [Features](Features.md), [Markdown Reference](Markdown-Reference.md), [Privacy and Security](Privacy-and-Security.md), and [Troubleshooting](Troubleshooting.md).