@bytechain.cn/colamd 1.5.0 → 1.5.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.trae/specs/optimize-theme-loading/checklist.md +20 -0
- package/.trae/specs/optimize-theme-loading/spec.md +103 -0
- package/.trae/specs/optimize-theme-loading/tasks.md +40 -0
- package/CHANGELOG.md +323 -0
- package/CLAUDE.md +56 -0
- package/README.md +422 -26
- package/README_CN.md +480 -28
- package/android/app/build/.npmkeep +0 -0
- package/android/app/build.gradle +76 -0
- package/android/app/capacitor.build.gradle +24 -0
- package/android/app/proguard-rules.pro +21 -0
- package/android/app/release.keystore +0 -0
- package/android/app/src/androidTest/java/com/getcapacitor/myapp/ExampleInstrumentedTest.java +26 -0
- package/android/app/src/main/AndroidManifest.xml +64 -0
- package/android/app/src/main/java/cn/bytechain/colamd/MainActivity.java +180 -0
- package/android/app/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/android/app/src/main/res/drawable/splash.png +0 -0
- package/android/app/src/main/res/drawable-land-hdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-land-mdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-land-xhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-land-xxhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-land-xxxhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-port-hdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-port-mdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-port-xhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-port-xxhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-port-xxxhdpi/splash.png +0 -0
- package/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +34 -0
- package/android/app/src/main/res/layout/activity_main.xml +12 -0
- package/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/android/app/src/main/res/values/ic_launcher_background.xml +4 -0
- package/android/app/src/main/res/values/strings.xml +7 -0
- package/android/app/src/main/res/values/styles.xml +22 -0
- package/android/app/src/main/res/xml/file_paths.xml +5 -0
- package/android/app/src/main/res/xml/network_security_config.xml +8 -0
- package/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java +18 -0
- package/android/build.gradle +29 -0
- package/android/capacitor.settings.gradle +21 -0
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/android/gradle.properties +22 -0
- package/android/gradlew +248 -0
- package/android/gradlew.bat +92 -0
- package/android/settings.gradle +5 -0
- package/android/variables.gradle +16 -0
- package/bytechain.cn-colamd-1.5.1-beta.2.tgz +0 -0
- package/capacitor.config.js +29 -0
- package/capacitor.config.ts +30 -0
- package/demo.md +191 -484
- package/dist/main/index.js +77 -46
- package/dist/renderer/assets/{arc-tTbbM8LO.js → arc-CPdeInCG.js} +1 -1
- package/dist/renderer/assets/{architectureDiagram-3BPJPVTR-CEgYow6c.js → architectureDiagram-3BPJPVTR-BAbnaR9G.js} +4 -3
- package/dist/renderer/assets/{blockDiagram-GPEHLZMM-LHyVtPwW.js → blockDiagram-GPEHLZMM-CYSWjnJg.js} +5 -4
- package/dist/renderer/assets/{c4Diagram-AAUBKEIU-C1P1eJrf.js → c4Diagram-AAUBKEIU-Rb1tstnr.js} +3 -2
- package/dist/renderer/assets/{channel-upve91Tq.js → channel-DpG2A6fE.js} +1 -1
- package/dist/renderer/assets/{chunk-2J33WTMH-lag2vhq9.js → chunk-2J33WTMH-DFc0Jxy_.js} +1 -1
- package/dist/renderer/assets/{chunk-4BX2VUAB-BXJ8Ggh-.js → chunk-4BX2VUAB-BhRxDTNn.js} +1 -1
- package/dist/renderer/assets/{chunk-55IACEB6-CiBpxRa1.js → chunk-55IACEB6-DEgMVBk8.js} +1 -1
- package/dist/renderer/assets/{chunk-727SXJPM-ODeKQFXC.js → chunk-727SXJPM-bjBIfiz8.js} +5 -5
- package/dist/renderer/assets/{chunk-AQP2D5EJ-BK7xJolB.js → chunk-AQP2D5EJ-DwQMzTzD.js} +3 -3
- package/dist/renderer/assets/{chunk-FMBD7UC4-BxpCZPtz.js → chunk-FMBD7UC4-CkphwJzs.js} +1 -1
- package/dist/renderer/assets/{chunk-ND2GUHAM-CqqaU9Ue.js → chunk-ND2GUHAM-oU09z4y4.js} +1 -1
- package/dist/renderer/assets/{chunk-QZHKN3VN-Biq_K124.js → chunk-QZHKN3VN-rCbVuPBn.js} +1 -1
- package/dist/renderer/assets/{classDiagram-v2-Q7XG4LA2-Cq95X99o.js → classDiagram-4FO5ZUOK-DGS2faoM.js} +7 -6
- package/dist/renderer/assets/{classDiagram-4FO5ZUOK-Cq95X99o.js → classDiagram-v2-Q7XG4LA2-DGS2faoM.js} +7 -6
- package/dist/renderer/assets/{cose-bilkent-S5V4N54A-XasiD0bu.js → cose-bilkent-S5V4N54A-iqY6-EwA.js} +2 -1
- package/dist/renderer/assets/{dagre-BM42HDAG-Nq84Gfx4.js → dagre-BM42HDAG-5t3X5sDa.js} +4 -3
- package/dist/renderer/assets/{diagram-2AECGRRQ-DwuB1GWt.js → diagram-2AECGRRQ-DzHiYDPh.js} +4 -3
- package/dist/renderer/assets/{diagram-5GNKFQAL-C2tgeI1h.js → diagram-5GNKFQAL-BiNv6Keq.js} +5 -4
- package/dist/renderer/assets/{diagram-KO2AKTUF-D5KzjNBc.js → diagram-KO2AKTUF-ClzeDG6f.js} +4 -3
- package/dist/renderer/assets/{diagram-LMA3HP47-C12xHS1c.js → diagram-LMA3HP47-CGkw7wII.js} +4 -3
- package/dist/renderer/assets/{diagram-OG6HWLK6-CnxI9oEa.js → diagram-OG6HWLK6-Dl-Hyk1_.js} +5 -4
- package/dist/renderer/assets/{erDiagram-TEJ5UH35-D_uPaKwn.js → erDiagram-TEJ5UH35-BxUN79Qb.js} +5 -4
- package/dist/renderer/assets/{flowDiagram-I6XJVG4X-B6q_1-tE.js → flowDiagram-I6XJVG4X-CzFk-KNI.js} +7 -6
- package/dist/renderer/assets/{ganttDiagram-6RSMTGT7-CFo7ifF9.js → ganttDiagram-6RSMTGT7-C2xl6Igx.js} +3 -2
- package/dist/renderer/assets/{gitGraphDiagram-PVQCEYII-WSexHTnq.js → gitGraphDiagram-PVQCEYII-_fn7XCa7.js} +5 -4
- package/dist/renderer/assets/{graph-DyX_9f6d.js → graph-CDoHYrHm.js} +1 -1
- package/dist/renderer/assets/index-B4uDgADr.js +530 -0
- package/dist/renderer/assets/index-CBcVpA3d.js +30 -0
- package/dist/renderer/assets/index-CGj1spkU.js +27 -0
- package/dist/renderer/assets/{index-dyHEFYvY.css → index-CeFpoCKV.css} +443 -400
- package/dist/renderer/assets/index-D4CPFkph.js +9 -0
- package/dist/renderer/assets/{index-DW7LS8C1.js → index-DAlXyxzt.js} +1183 -346
- package/dist/renderer/assets/index-DxOzbfR-.js +110 -0
- package/dist/renderer/assets/index-Y89U1ptl.js +9 -0
- package/dist/renderer/assets/{infoDiagram-5YYISTIA-DaeJdLRq.js → infoDiagram-5YYISTIA-DL6XIxLz.js} +3 -2
- package/dist/renderer/assets/{ishikawaDiagram-YF4QCWOH-DDCZc35f.js → ishikawaDiagram-YF4QCWOH-BUZLjRo-.js} +2 -1
- package/dist/renderer/assets/{journeyDiagram-JHISSGLW-BEdmpAgl.js → journeyDiagram-JHISSGLW-C4rH_mQM.js} +5 -4
- package/dist/renderer/assets/{kanban-definition-UN3LZRKU-BEFtQcFb.js → kanban-definition-UN3LZRKU-DRbrBcWV.js} +3 -2
- package/dist/renderer/assets/{layout-CAJgQHdw.js → layout-DZl4n4qu.js} +2 -2
- package/dist/renderer/assets/{linear-B2ggJ8Am.js → linear-B0Krxg21.js} +1 -1
- package/dist/renderer/assets/{mindmap-definition-RKZ34NQL-DSxVgHB5.js → mindmap-definition-RKZ34NQL-DdmPsWrn.js} +4 -3
- package/dist/renderer/assets/{pieDiagram-4H26LBE5-CwYoJBuL.js → pieDiagram-4H26LBE5-BPZLqwG0.js} +5 -4
- package/dist/renderer/assets/preload-helper-tXtZnHb0.js +88 -0
- package/dist/renderer/assets/{quadrantDiagram-W4KKPZXB-CST9Fvg9.js → quadrantDiagram-W4KKPZXB-Dr-oWRk9.js} +3 -2
- package/dist/renderer/assets/{requirementDiagram-4Y6WPE33-DtrH52jS.js → requirementDiagram-4Y6WPE33-B6QZd0lo.js} +4 -3
- package/dist/renderer/assets/{sankeyDiagram-5OEKKPKP-ca1tPzJ_.js → sankeyDiagram-5OEKKPKP-Cyl9ojEt.js} +2 -1
- package/dist/renderer/assets/{sequenceDiagram-3UESZ5HK-Dfp1EJZ7.js → sequenceDiagram-3UESZ5HK-D48Yr9T6.js} +4 -3
- package/dist/renderer/assets/{stateDiagram-AJRCARHV-Bha2QoNB.js → stateDiagram-AJRCARHV-qyb8ETsa.js} +7 -6
- package/dist/renderer/assets/{stateDiagram-v2-BHNVJYJU-DWgFUYu1.js → stateDiagram-v2-BHNVJYJU-DmDOyyrJ.js} +5 -4
- package/dist/renderer/assets/{timeline-definition-PNZ67QCA-C3h_-OTj.js → timeline-definition-PNZ67QCA-C-KQxTi1.js} +3 -2
- package/dist/renderer/assets/{vennDiagram-CIIHVFJN-DFzjSrZi.js → vennDiagram-CIIHVFJN-BdaZlnH-.js} +2 -1
- package/dist/renderer/assets/{wardley-L42UT6IY-Cx-VbqoS.js → wardley-L42UT6IY-b-_GPpqL.js} +1 -1
- package/dist/renderer/assets/{wardleyDiagram-YWT4CUSO-S2D9XqX6.js → wardleyDiagram-YWT4CUSO-B2hBE-EE.js} +4 -3
- package/dist/renderer/assets/web-BKE0SH0E.js +36 -0
- package/dist/renderer/assets/web-CBsFp24u.js +564 -0
- package/dist/renderer/assets/web-Dc8YgoHP.js +24 -0
- package/dist/renderer/assets/web-TfDzToU7.js +58 -0
- package/dist/renderer/assets/{xychartDiagram-2RQKCTM6-Cfxigbts.js → xychartDiagram-2RQKCTM6-CSvswDTY.js} +3 -2
- package/dist/renderer/index.html +62 -3
- package/docs/academic-demo.md +566 -0
- package/docs/demo.html +748 -0
- package/docs/demo.md +546 -0
- package/docs/demo.pdf +0 -0
- package/docs/theme-paradigm.md +658 -0
- package/electron-builder.yml +7 -0
- package/electron.vite.config.js +31 -0
- package/electron.vite.config.ts +1 -1
- package/ios/App/App/AppDelegate.swift +49 -0
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png +0 -0
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/ios/App/App/Assets.xcassets/Contents.json +6 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +23 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/ios/App/App/Base.lproj/LaunchScreen.storyboard +32 -0
- package/ios/App/App/Base.lproj/Main.storyboard +19 -0
- package/ios/App/App/Info.plist +49 -0
- package/ios/App/App.xcodeproj/project.pbxproj +408 -0
- package/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/App/Podfile +28 -0
- package/package.json +23 -3
- package/resources/templates/slides/template-forest-ink.html +540 -0
- package/scripts/generate-icons.js +102 -0
- package/src/main/index.ts +87 -63
- package/src/preload/index.d.ts +51 -0
- package/src/preload/index.js +70 -0
- package/src/renderer/capacitor-api.ts +713 -0
- package/src/renderer/editor/editor.ts +87 -4
- package/src/renderer/editor/plugins/index.ts +24 -32
- package/src/renderer/editor/plugins/math-plugin.ts +1 -1
- package/src/renderer/editor/plugins/mermaid-plugin-custom.css +13 -398
- package/src/renderer/editor/plugins/mermaid-plugin.ts +62 -71
- package/src/renderer/editor/plugins/themes/base/dark.css +23 -0
- package/src/renderer/editor/plugins/themes/base/elegant.css +32 -0
- package/src/renderer/editor/plugins/themes/base/light.css +20 -0
- package/src/renderer/editor/plugins/themes/base/newsprint.css +27 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/academic.css +43 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/dark.css +20 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/elegant.css +24 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/light.css +21 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/newsprint.css +26 -0
- package/src/renderer/editor/plugins/themes/components/mermaid/variables.css +592 -0
- package/src/renderer/editor/plugins/themes/foundation.css +143 -0
- package/src/renderer/editor/plugins/themes/theme-manager.ts +92 -0
- package/src/renderer/env.d.ts +4 -1
- package/src/renderer/index.html +59 -1
- package/src/renderer/main.ts +432 -57
- package/src/renderer/mobile.css +429 -0
- package/themes/README.md +3 -0
- package/themes/academic-paper.css +1321 -0
- package/themes/elegant.css +14 -7
- package/themes/forest-ink.css +664 -0
- package/themes/pixso-design.css +1261 -0
- package/themes/swiss-design.css +596 -0
- package/themes/template.css +498 -0
- package/tsconfig.main.json +1 -0
- package/tsconfig.main.tsbuildinfo +1 -0
- package/tsconfig.preload.json +1 -0
- package/tsconfig.preload.tsbuildinfo +1 -0
- package/tsconfig.renderer.json +1 -0
- package/tsconfig.renderer.tsbuildinfo +1 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/.trae/documents/fix-mermaid-colors-and-sankey.md +0 -50
- package/src/renderer/themes/theme-manager.ts +0 -40
- /package/src/renderer/{themes → editor/plugins/themes}/base.css +0 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Real-time collaboration between humans and AI agents — see your agent's change
|
|
|
11
11
|
|
|
12
12
|
**This Extended Edition**: [git@github.com:byteuser1977/ColaMD-extend.git](https://github.com/byteuser1977/ColaMD-extend)
|
|
13
13
|
|
|
14
|
-
[Features](#features) | [Renderer Plugins](#renderer-plugin-system) | [Plug Menu](#plug-menu--plugin-render-control) | [Quick Start](#quick-start) | [Themes](#theme-system) | [Architecture](#technical-architecture) | [中文](README_CN.md)
|
|
14
|
+
[Features](#features) | [Renderer Plugins](#renderer-plugin-system) | [Plug Menu](#plug-menu--plugin-render-control) | [Quick Start](#quick-start) | [Mobile Build](#mobile-build--capacitor-6) | [Themes](#theme-system) | [Architecture](#technical-architecture) | [中文](README_CN.md)
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
@@ -38,18 +38,39 @@ This repository extends **[marswaveai/ColaMD](https://github.com/marswaveai/cola
|
|
|
38
38
|
| Math support | ❌ | ✅ KaTeX inline/block equations, live editing, PNG export |
|
|
39
39
|
| Diagram support | ❌ | ✅ Mermaid full-type diagrams (17+ types), multi-theme adaptation, PNG export |
|
|
40
40
|
| Dual-mode toggle | N/A | ✅ Each plugin supports **Rendered / Source Edit mode** one-click toggle |
|
|
41
|
+
| Mobile platform | ❌ Desktop only | ✅ **Android (.apk) + iOS (.ipa)** via Capacitor 6 |
|
|
41
42
|
|
|
42
43
|
> All original features are fully preserved: Agent real-time sync, activity indicator, WYSIWYG editor, slide system, themes & export, etc.
|
|
43
44
|
|
|
44
|
-
### Demo
|
|
45
|
+
### Demo Documents
|
|
45
46
|
|
|
46
|
-
This project includes
|
|
47
|
+
This project includes comprehensive demo documents to showcase the plugin capabilities:
|
|
48
|
+
|
|
49
|
+
#### General Demo — [`demo.md`](docs/demo.md)
|
|
50
|
+
|
|
51
|
+
A comprehensive demo covering:
|
|
47
52
|
|
|
48
53
|
- **Math Equations**: 7 inline equations + 6 block equations (including systems of equations, matrices, physics formulas)
|
|
49
54
|
- **Mermaid Diagrams**: All 17 diagram types (flowchart, sequence, class, state, ER, Gantt, pie, journey, git graph, mindmap, timeline, quadrant, XY chart, C4 context, Sankey, block, complex clustered)
|
|
50
55
|
- **Mixed Content**: Formulas and diagrams rendered together in the same document
|
|
51
56
|
|
|
52
|
-
Open `demo.md` to fully test the plugin rendering, mode switching, source editing, and PNG export capabilities of the extended ColaMD.
|
|
57
|
+
Open `docs/demo.md` to fully test the plugin rendering, mode switching, source editing, and PNG export capabilities of the extended ColaMD.
|
|
58
|
+
|
|
59
|
+
#### Academic Paper Demo — [`academic-demo.md`](docs/academic-demo.md) 🆕
|
|
60
|
+
|
|
61
|
+
A real-world academic paper demonstrating the enhanced **Academic Paper theme** (`academic-paper.css`):
|
|
62
|
+
|
|
63
|
+
- **Full Academic Structure**: Abstract, keywords, CLC number, document identifier, introduction, methodology, tables, and references
|
|
64
|
+
- **GB/T 7713 Compliance**: Follows Chinese academic paper formatting standards with proper typography (SimHei headings + SimSun body text)
|
|
65
|
+
- **Three-Line Tables**: Academic-standard table format (top line + header bottom line + bottom line, no vertical borders)
|
|
66
|
+
- **Mermaid Diagrams**: Complex organizational charts with custom color schemes optimized for print
|
|
67
|
+
- **Mixed Content**: Mathematical formulas, Mermaid diagrams, tables, and citations in a single document
|
|
68
|
+
|
|
69
|
+
Open `docs/academic-demo.md` in ColaMD with the **Academic Paper** theme active to see the full effect. This demo showcases:
|
|
70
|
+
- Professional academic typography (黑体 for headings, 宋体 for body text)
|
|
71
|
+
- Print-optimized Mermaid diagram rendering
|
|
72
|
+
- Proper code block and blockquote styling for academic contexts
|
|
73
|
+
- Footnotes and reference section formatting
|
|
53
74
|
|
|
54
75
|
---
|
|
55
76
|
|
|
@@ -240,6 +261,7 @@ graph TD
|
|
|
240
261
|
| **Dark** | GitHub Dark | System default | `#0d1117` background, `#8b949e` border/text |
|
|
241
262
|
| **Elegant** | Custom warm palette | LXGW WenKai | `#e8e2db` background, warm brown cScale |
|
|
242
263
|
| **Newsprint** | Print style | PT Serif | Serif font, newsprint texture |
|
|
264
|
+
| **Forest Ink** (custom) | Forest green palette | Noto Serif SC | `#f5f1e8` paper base, `#3d6b4a` forest green accent, ink-green lines |
|
|
243
265
|
|
|
244
266
|
---
|
|
245
267
|
|
|
@@ -373,6 +395,218 @@ npm run dist:linux # Linux (.AppImage / .deb)
|
|
|
373
395
|
| macOS | `.dmg` |
|
|
374
396
|
| Windows | `.exe` |
|
|
375
397
|
| Linux | `.AppImage` / `.deb` |
|
|
398
|
+
| Android | `.apk` (via Capacitor) |
|
|
399
|
+
| iOS | `.ipa` (via Capacitor, requires Xcode) |
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Mobile Build — Capacitor 6
|
|
404
|
+
|
|
405
|
+
> Starting from v1.5.1, ColaMD supports building native mobile apps via **[Capacitor 6](https://capacitorjs.com/)** — the cross-platform runtime by Ionic. The same codebase that powers the Electron desktop app now runs on Android and iOS devices.
|
|
406
|
+
|
|
407
|
+
### Architecture: Dual-Platform Bridge
|
|
408
|
+
|
|
409
|
+
ColaMD uses an **auto-detection bridge layer** that seamlessly switches between Electron (desktop) and Capacitor (mobile) APIs at runtime:
|
|
410
|
+
|
|
411
|
+
```
|
|
412
|
+
┌─────────────────────────────────────┐
|
|
413
|
+
│ src/renderer/main.ts │
|
|
414
|
+
│ api = electronAPI || capacitorAPI │ ← Auto-detect platform
|
|
415
|
+
├──────────────┬──────────────────────┤
|
|
416
|
+
│ Electron │ Capacitor 6 │
|
|
417
|
+
│ (Desktop) │ (Mobile) │
|
|
418
|
+
│ │ │
|
|
419
|
+
│ IPC comm │ Filesystem Plugin │
|
|
420
|
+
│ dialog │ Share Plugin │
|
|
421
|
+
│ shell.open │ App Plugin │
|
|
422
|
+
│ fs module │ localStorage storage │
|
|
423
|
+
└──────────────┴──────────────────────┘
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**Key files**:
|
|
427
|
+
- [`capacitor-api.ts`](src/renderer/capacitor-api.ts) — Full Capacitor bridge implementing the same API surface as `electronAPI`
|
|
428
|
+
- [`capacitor.config.ts`](capacitor.config.ts) — Capacitor configuration (appId, webDir, plugins)
|
|
429
|
+
- [`mobile.css`](src/renderer/mobile.css) — Touch-optimized responsive styles
|
|
430
|
+
- [`MainActivity.java`](android/app/src/main/java/cn/bytechain/colamd/MainActivity.java) — Android WebView IME support
|
|
431
|
+
|
|
432
|
+
### Technology Stack for Mobile
|
|
433
|
+
|
|
434
|
+
| Component | Technology | Purpose |
|
|
435
|
+
|-----------|------------|---------|
|
|
436
|
+
| **Runtime** | Capacitor 6.x | Cross-platform native bridge |
|
|
437
|
+
| **WebView Engine** | Android WebView / iOS WKWebView | Renders web content |
|
|
438
|
+
| **File Access** | `@capacitor/filesystem` | Read/write local files |
|
|
439
|
+
| **File Picker** | `@capawesome/capacitor-file-picker` | Native file selection dialog |
|
|
440
|
+
| **Sharing** | `@capacitor/share` | System share sheet integration |
|
|
441
|
+
| **App Lifecycle** | `@capacitor/app` | Handle app events (pause, resume) |
|
|
442
|
+
| **Status Bar** | `@capacitor/status-bar` | Status bar styling |
|
|
443
|
+
| **Haptics** | `@capacitor/haptics` | Haptic feedback |
|
|
444
|
+
|
|
445
|
+
### Prerequisites for Mobile Build
|
|
446
|
+
|
|
447
|
+
| Platform | Requirements |
|
|
448
|
+
|----------|-------------|
|
|
449
|
+
| **Android** | Android Studio + SDK (API 34+) + **Java 21** (`brew install openjdk@21`) |
|
|
450
|
+
| **iOS** | Xcode 15+ + CocoaPods + macOS |
|
|
451
|
+
|
|
452
|
+
### Quick Start — Android
|
|
453
|
+
|
|
454
|
+
```bash
|
|
455
|
+
# 1. Install dependencies (Capacitor packages included)
|
|
456
|
+
npm install
|
|
457
|
+
|
|
458
|
+
# 2. Build web assets
|
|
459
|
+
npm run build
|
|
460
|
+
|
|
461
|
+
# 3. Sync to Android platform
|
|
462
|
+
npx cap sync android
|
|
463
|
+
|
|
464
|
+
# 4. Open in Android Studio
|
|
465
|
+
npx cap open android
|
|
466
|
+
|
|
467
|
+
# 5. Or build APK directly
|
|
468
|
+
npm run cap:build:android
|
|
469
|
+
# Output: android/app/build/outputs/apk/debug/app-debug.apk
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Quick Start — iOS
|
|
473
|
+
|
|
474
|
+
```bash
|
|
475
|
+
# 1. Sync to iOS platform
|
|
476
|
+
npx cap sync ios
|
|
477
|
+
|
|
478
|
+
# 2. Open in Xcode
|
|
479
|
+
npx cap open ios
|
|
480
|
+
|
|
481
|
+
# 3. Build in Xcode (⌘R) or use:
|
|
482
|
+
npm run cap:build:ios
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Build Commands
|
|
486
|
+
|
|
487
|
+
| Command | Description | Output |
|
|
488
|
+
|---------|-------------|--------|
|
|
489
|
+
| `npm run cap:sync` | Sync web assets to all platforms | Updated `android/` and `ios/` |
|
|
490
|
+
| `npm run cap:open:android` | Open Android project in Android Studio | — |
|
|
491
|
+
| `npm run cap:open:ios` | Open iOS project in Xcode | — |
|
|
492
|
+
| `npm run cap:run:android` | Build → Sync → Run on device/emulator | Live app on device |
|
|
493
|
+
| `npm run cap:run:ios` | Build → Sync → Run on simulator | Live app in simulator |
|
|
494
|
+
| `npm run cap:build:android` | Build **Debug APK** | `android/app/build/outputs/apk/debug/app-debug.apk` |
|
|
495
|
+
| `npm run cap:build:android:release` | Build **Release APK** (signed) | `android/app/build/outputs/apk/release/app-release.apk` |
|
|
496
|
+
| `npm run cap:build:ios` | Prepare iOS project for Xcode build | — |
|
|
497
|
+
|
|
498
|
+
### Release Build — Android
|
|
499
|
+
|
|
500
|
+
For production release builds, the project includes a signing configuration:
|
|
501
|
+
|
|
502
|
+
```bash
|
|
503
|
+
# Build signed release APK
|
|
504
|
+
npm run cap:build:android:release
|
|
505
|
+
|
|
506
|
+
# Output location
|
|
507
|
+
android/app/build/outputs/apk/release/app-release.apk
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
The release keystore is located at `android/app/release.keystore` with credentials stored in `build.gradle`.
|
|
511
|
+
|
|
512
|
+
### Release Build — iOS
|
|
513
|
+
|
|
514
|
+
1. Open the project in Xcode:
|
|
515
|
+
```bash
|
|
516
|
+
npx cap open ios
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
2. In Xcode:
|
|
520
|
+
- Select **Product → Archive**
|
|
521
|
+
- Once archived, click **Distribute App**
|
|
522
|
+
- Choose distribution method (App Store Connect, Ad Hoc, etc.)
|
|
523
|
+
|
|
524
|
+
3. For App Store submission:
|
|
525
|
+
- Configure signing certificates in Xcode
|
|
526
|
+
- Upload to App Store Connect via Xcode or Transporter
|
|
527
|
+
|
|
528
|
+
### Chinese IME Support (Android)
|
|
529
|
+
|
|
530
|
+
ColaMD includes special handling for Chinese/Japanese/Korean input methods on Android WebView:
|
|
531
|
+
|
|
532
|
+
**Implementation** ([`MainActivity.java`](android/app/src/main/java/cn/bytechain/colamd/MainActivity.java)):
|
|
533
|
+
- WebView focus optimization for IME connection
|
|
534
|
+
- Soft keyboard auto-show on focus
|
|
535
|
+
- Touch mode focusability enabled
|
|
536
|
+
|
|
537
|
+
**Known Limitations**:
|
|
538
|
+
- ProseMirror/Milkdown has known IME composition issues on Android WebView
|
|
539
|
+
- Some input methods may require tapping the editor area to activate
|
|
540
|
+
- If input seems stuck, try tapping elsewhere then back to the editor
|
|
541
|
+
|
|
542
|
+
### File Picker Integration
|
|
543
|
+
|
|
544
|
+
Mobile platforms use `@capawesome/capacitor-file-picker` for native file selection:
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
// Example usage (internal)
|
|
548
|
+
const result = await FilePicker.pickFiles({
|
|
549
|
+
types: ['text/markdown', 'text/plain'],
|
|
550
|
+
multiple: false,
|
|
551
|
+
readData: true,
|
|
552
|
+
})
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
**Supported file types**: `.md`, `.markdown`, `.txt`, `.css` (for themes)
|
|
556
|
+
|
|
557
|
+
### Mobile Features & Limitations
|
|
558
|
+
|
|
559
|
+
| Feature | Status | Notes |
|
|
560
|
+
|---------|--------|-------|
|
|
561
|
+
| Markdown editing ✏️ | ✅ Fully supported | Milkdown editor runs in WebView |
|
|
562
|
+
| Math rendering (KaTeX) 📐 | ✅ Fully supported | Same as desktop |
|
|
563
|
+
| Mermaid diagrams 🔀 | ✅ Fully supported | SVG renders in WebView |
|
|
564
|
+
| Plugin system | ✅ Fully supported | Toggle via UI, state in localStorage |
|
|
565
|
+
| Themes | ✅ Fully supported | All themes work on mobile |
|
|
566
|
+
| File open/save | ✅ Supported | Native file picker via FilePicker plugin |
|
|
567
|
+
| Chinese/Japanese/Korean input | ⚠️ Partial | IME support implemented, may have edge cases |
|
|
568
|
+
| Export HTML/PDF | ⚠️ Partial | HTML export works; PDF uses `window.print()` |
|
|
569
|
+
| Agent file watch | ⚠️ Polling mode | Uses 2s interval instead of `fs.watch` |
|
|
570
|
+
| Slides preview | ⚠️ Limited | Opens new browser window on desktop; basic on mobile |
|
|
571
|
+
| External links | ✅ Supported | Opens in system browser via `_system` target |
|
|
572
|
+
|
|
573
|
+
### Responsive Design
|
|
574
|
+
|
|
575
|
+
The mobile CSS ([`mobile.css`](src/renderer/mobile.css)) provides:
|
|
576
|
+
|
|
577
|
+
- **Touch optimization**: Disabled tap highlight, proper touch-action
|
|
578
|
+
- **Safe area support**: Automatic padding for notched devices (iPhone X+, modern Android)
|
|
579
|
+
- **Responsive breakpoints**:
|
|
580
|
+
- ≤768px: Tablet layout adjustments
|
|
581
|
+
- ≤480px: Phone layout with smaller fonts
|
|
582
|
+
- **Editor adaptation**: Fixed-position editor filling viewport below header
|
|
583
|
+
- **Scroll behavior**: `-webkit-overflow-scrolling: touch` for smooth scrolling
|
|
584
|
+
- **Context menu**: Touch-friendly with larger tap targets (12px padding, 15px font)
|
|
585
|
+
|
|
586
|
+
### Troubleshooting Mobile Issues
|
|
587
|
+
|
|
588
|
+
**Chinese input not working**:
|
|
589
|
+
- Tap the editor area to ensure focus
|
|
590
|
+
- Try switching to another app and back
|
|
591
|
+
- Check that the soft keyboard is visible
|
|
592
|
+
|
|
593
|
+
**File picker not opening**:
|
|
594
|
+
- Ensure storage permissions are granted
|
|
595
|
+
- On Android 11+, check "Allow all the time" for storage permission
|
|
596
|
+
|
|
597
|
+
**App crashes on launch**:
|
|
598
|
+
- Run `npx cap sync android` to ensure latest web assets
|
|
599
|
+
- Check Android Studio logcat for errors
|
|
600
|
+
- Ensure Java 21 is correctly configured
|
|
601
|
+
|
|
602
|
+
**Build fails**:
|
|
603
|
+
```bash
|
|
604
|
+
# Clean and rebuild
|
|
605
|
+
cd android
|
|
606
|
+
./gradlew clean
|
|
607
|
+
cd ..
|
|
608
|
+
npm run cap:build:android
|
|
609
|
+
```
|
|
376
610
|
|
|
377
611
|
---
|
|
378
612
|
|
|
@@ -387,32 +621,57 @@ ColaMD includes **4 built-in themes**, and all renderer plugins automatically ad
|
|
|
387
621
|
| **Elegant** | `theme-elegant` | Elegant theme, warm serif style (**default theme**) |
|
|
388
622
|
| **Newsprint** | `theme-newsprint` | Newsprint style |
|
|
389
623
|
|
|
390
|
-
|
|
624
|
+
Downloadable external themes (located in [`themes/`](themes/) directory):
|
|
625
|
+
|
|
626
|
+
| Theme File | Style Description |
|
|
627
|
+
|------------|-------------------|
|
|
628
|
+
| [elegant.css](themes/elegant.css) | Warm serif with terracotta accents, LXGW WenKai font |
|
|
629
|
+
| [guizang.css](themes/guizang.css) | Ancient Guizang style, ochre accents, ink-black code blocks |
|
|
630
|
+
| [forest-ink.css](themes/forest-ink.css) | 🌲 Forest Ink, warm paper base + forest green ink text + forest green accent |
|
|
631
|
+
| [academic-paper.css](themes/academic-paper.css) | 📄 **Academic Paper (Enhanced)** — GB/T 7713 compliant, SimHei headings + SimSun body text, three-line tables, print-optimized Mermaid diagrams, footnotes & references styling. See [`academic-demo.md`](docs/academic-demo.md) for a complete example |
|
|
632
|
+
| [pixso-design.css](themes/pixso-design.css) | 🎨 Pixso Design, modern design system style |
|
|
633
|
+
| [swiss-design.css](themes/swiss-design.css) | 🇨🇭 **Swiss Design (International Typographic Style)** — Pure black-white-red color system, geometric sans-serif fonts (Helvetica/Inter), grid-based layout with generous whitespace, form follows function. Minimalist and restrained aesthetic inspired by Swiss International Typographic Style |
|
|
391
634
|
|
|
392
|
-
|
|
635
|
+
Custom theme support: Place CSS files in `~/.colamd/themes/` directory, then import via **Theme > Import Theme**. Imported themes persist across sessions.
|
|
393
636
|
|
|
394
637
|
---
|
|
395
638
|
|
|
396
639
|
## Technical Architecture
|
|
397
640
|
|
|
398
641
|
```
|
|
399
|
-
|
|
400
|
-
│
|
|
401
|
-
│
|
|
402
|
-
│
|
|
403
|
-
│ │
|
|
404
|
-
│
|
|
405
|
-
│
|
|
406
|
-
│
|
|
407
|
-
│
|
|
408
|
-
│
|
|
409
|
-
│
|
|
410
|
-
│
|
|
411
|
-
│
|
|
412
|
-
│
|
|
413
|
-
│
|
|
414
|
-
│
|
|
415
|
-
|
|
642
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
643
|
+
│ ColaMD — Dual Platform │
|
|
644
|
+
│ │
|
|
645
|
+
│ ┌──────────────────────┐ ┌────────────────────────────┐ │
|
|
646
|
+
│ │ Desktop (Electron) │ │ Mobile (Capacitor 6) │ │
|
|
647
|
+
│ │ │ │ │ │
|
|
648
|
+
│ │ ┌─────────┐ ┌──────┐ │ │ ┌──────────────────────┐ │ │
|
|
649
|
+
│ │ │ Main │ │Preload│ │ │ │ Capacitor Runtime │ │ │
|
|
650
|
+
│ │ │Process │ │Bridge │ │ │ │ (WebView / WKWebView)│ │ │
|
|
651
|
+
│ │ └────┬────┘ └──┬───┘ │ │ └──────────┬───────────┘ │ │
|
|
652
|
+
│ │ │ IPC │ │ │ │ Plugins │ │
|
|
653
|
+
│ │ └────┬────┘ │ │ ├─ Filesystem │ │
|
|
654
|
+
│ │ ▼ │ │ ├─ Share │ │
|
|
655
|
+
│ │ ┌─────────────────┐ │ │ ├─ App │ │
|
|
656
|
+
│ │ │ Renderer │ │ │ ├─ StatusBar │ │
|
|
657
|
+
│ │ │ Process │◄─┼───┼─────────────┤ │ │
|
|
658
|
+
│ │ └────────┬────────┘ │ │ └─ Haptics │ │
|
|
659
|
+
│ │ ▼ │ └──────────────┬───────────────┘ │
|
|
660
|
+
│ │ ┌──────────────────┐ │ │ │
|
|
661
|
+
│ │ │ Milkdown Editor │◄┘ │ │
|
|
662
|
+
│ │ │ (ProseMirror) │ │ │
|
|
663
|
+
│ │ │ ┌────────────┐ │ │ │
|
|
664
|
+
│ │ │ │Plugin Syst.│ │ │ │
|
|
665
|
+
│ │ │ │├─ 📐 Math │ │ │ │
|
|
666
|
+
│ │ │ │└─ 🔀Mermaid│ │ │ │
|
|
667
|
+
│ │ │ └────────────┘ │ │ │
|
|
668
|
+
│ │ └──────────────────┘ │ │
|
|
669
|
+
│ └──────────────────────┘ │ │
|
|
670
|
+
│ ┌──────────────────────────┘ │
|
|
671
|
+
│ ▼ │
|
|
672
|
+
│ Auto-detection: │
|
|
673
|
+
│ api = electronAPI || capacitorAPI │
|
|
674
|
+
└─────────────────────────────────────────────────────────────┘
|
|
416
675
|
```
|
|
417
676
|
|
|
418
677
|
### Tech Stack
|
|
@@ -420,6 +679,7 @@ Community-contributed themes can be downloaded from the [`themes/`](themes/) fol
|
|
|
420
679
|
| Technology | Purpose | Version | Documentation |
|
|
421
680
|
|------------|---------|---------|---------------|
|
|
422
681
|
| [Electron](https://www.electronjs.org/) | Cross-platform desktop framework | ^34.0.0 | [📖 Docs](https://www.electronjs.org/docs/latest/) |
|
|
682
|
+
| [Capacitor](https://capacitorjs.com/) | Cross-platform mobile runtime (Android/iOS) | ^6.2.1 | [📖 Docs](https://capacitorjs.com/docs/) |
|
|
423
683
|
| [Milkdown](https://milkdown.dev/) | WYSIWYG Markdown editor core (ProseMirror-based) | ^7.19.2 | [📖 Docs](https://milkdown.dev/docs) |
|
|
424
684
|
| [ProseMirror](https://prosemirror.net/) | Underlying rich text editing engine | — | [📖 Docs](https://prosemirror.net/docs/) |
|
|
425
685
|
| [KaTeX](https://katex.org/) | Math equation rendering engine | ^0.16.46 | [📖 Docs](https://katex.org/docs/) |
|
|
@@ -428,7 +688,7 @@ Community-contributed themes can be downloaded from the [`themes/`](themes/) fol
|
|
|
428
688
|
| [electron-vite](https://electron-vite.org/) | Electron build toolchain | ^3.0.0 | [📖 Docs](https://electron-vite.org/guide/) |
|
|
429
689
|
| [Vite](https://vitejs.dev/) | Underlying build engine | ^6.0.0 | [📖 Docs](https://vitejs.dev/guide/) |
|
|
430
690
|
|
|
431
|
-
> 💡 **Dev Tip**: The official documentation of each library is the best reference for developing new plugins and custom features. In particular, the [KaTeX supported syntax](https://katex.org/docs/supported.html)
|
|
691
|
+
> 💡 **Dev Tip**: The official documentation of each library is the best reference for developing new plugins and custom features. In particular, the [KaTeX supported syntax](https://katex.org/docs/supported.html), [Mermaid diagram syntax](https://mermaid.js.org/intro/syntax-reference.html), and [Capacitor plugins API](https://capacitorjs.com/docs/apis) are essential for extending capabilities across platforms.
|
|
432
692
|
|
|
433
693
|
### Project Structure
|
|
434
694
|
|
|
@@ -437,12 +697,15 @@ src/
|
|
|
437
697
|
├── main/
|
|
438
698
|
│ └── index.ts # Main process: window management, file I/O, menus, file watching
|
|
439
699
|
├── preload/
|
|
440
|
-
│ └── index.ts # Secure IPC bridge layer
|
|
700
|
+
│ └── index.ts # Secure IPC bridge layer (Electron)
|
|
441
701
|
└── renderer/
|
|
442
702
|
├── index.html # Entry HTML
|
|
443
|
-
├── main.ts # Renderer
|
|
703
|
+
├── main.ts # Renderer entry: auto-detects Electron or Capacitor
|
|
704
|
+
├── capacitor-api.ts # ★ Capacitor bridge layer (replaces Electron APIs on mobile)
|
|
705
|
+
├── mobile.css # ★ Touch-optimized responsive styles
|
|
444
706
|
├── editor/
|
|
445
707
|
│ ├── editor.ts # Editor orchestration core (plugin integration)
|
|
708
|
+
│ └── plugins/ # ★ Renderer plugin system
|
|
446
709
|
│ ├── html-view.ts # HTML inline node view
|
|
447
710
|
│ └── plugins/ # ★ Renderer plugin system
|
|
448
711
|
│ ├── index.ts # Plugin manager (register/query/toggle)
|
|
@@ -465,6 +728,139 @@ The entire project has only **5 runtime dependencies** + **6 dev dependencies**,
|
|
|
465
728
|
|
|
466
729
|
---
|
|
467
730
|
|
|
731
|
+
## Inline SVG Guide
|
|
732
|
+
|
|
733
|
+
> ⚠️ **Important**: ColaMD uses remark/rehype to parse Markdown, where **blank lines act as paragraph separators**. For inline SVG to render correctly, the entire HTML block (including `<div>`, `<svg>`, `<p>` tags) **must be on a single line without any line breaks**.
|
|
734
|
+
|
|
735
|
+
### Why Single-Line Format?
|
|
736
|
+
|
|
737
|
+
ColaMD's parsing pipeline:
|
|
738
|
+
|
|
739
|
+
```
|
|
740
|
+
Markdown Source
|
|
741
|
+
↓
|
|
742
|
+
remark-parse (Markdown → MDAST)
|
|
743
|
+
↓
|
|
744
|
+
remark plugins processing
|
|
745
|
+
↓
|
|
746
|
+
Blank line detection: encountering blank line → creates new paragraph node
|
|
747
|
+
↓
|
|
748
|
+
rehype (MDAST → HAST)
|
|
749
|
+
↓
|
|
750
|
+
ProseMirror serialization
|
|
751
|
+
↓ Each paragraph → independent htmlSchema.node
|
|
752
|
+
↓
|
|
753
|
+
html-view.ts injects into DOM
|
|
754
|
+
↓
|
|
755
|
+
Final output: <span class="milkdown-html-inline">single block</span>
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
**Multi-line format consequence**:
|
|
759
|
+
|
|
760
|
+
```html
|
|
761
|
+
<!-- If SVG is split across multiple lines (with blank lines) -->
|
|
762
|
+
|
|
763
|
+
Markdown:
|
|
764
|
+
<div>
|
|
765
|
+
<svg>
|
|
766
|
+
<defs>...</defs>
|
|
767
|
+
|
|
768
|
+
<rect/>
|
|
769
|
+
|
|
770
|
+
<circle/>
|
|
771
|
+
</svg>
|
|
772
|
+
</div>
|
|
773
|
+
|
|
774
|
+
Exported HTML:
|
|
775
|
+
<p><span>...<svg><defs>...</defs></svg></span></p> ← Block 1
|
|
776
|
+
<p><span> <rect/></span></p> ← Block 2 (independent!)
|
|
777
|
+
<p><span> <circle/></span></p> ← Block 3 (independent!)
|
|
778
|
+
|
|
779
|
+
Result: ❌ SVG fragmented, cannot render correctly
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
**Single-line format effect**:
|
|
783
|
+
|
|
784
|
+
```html
|
|
785
|
+
<!-- Entire content on one line (no blank lines) -->
|
|
786
|
+
|
|
787
|
+
Markdown:
|
|
788
|
+
<div><svg><defs>...</defs><rect/><circle/></svg><p>Caption</p></div>
|
|
789
|
+
|
|
790
|
+
Exported HTML:
|
|
791
|
+
<p><span>
|
|
792
|
+
<div><svg>complete content</svg><p>Caption</p></div>
|
|
793
|
+
</span></p>
|
|
794
|
+
|
|
795
|
+
Result: ✅ Complete SVG renders correctly
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### SVG Specification Requirements
|
|
799
|
+
|
|
800
|
+
| # | Rule | Importance | Description |
|
|
801
|
+
|---|------|------------|-------------|
|
|
802
|
+
| 1 | 🔴 **Single-line compression** | **Required** | Entire `<div>` block must not contain line breaks |
|
|
803
|
+
| 2 | ✅ **Tag closure** | Required | All tags must be properly closed or self-closing |
|
|
804
|
+
| 3 | ✅ **Namespace** | Required | Must include `xmlns="http://www.w3.org/2000/svg"` |
|
|
805
|
+
| 4 | **Size matching** | Required | `width`/`height` must match `viewBox` |
|
|
806
|
+
| 5 | **Double quotes** | Recommended | All attribute values should use double quotes |
|
|
807
|
+
| 6 | **ASCII characters** | Recommended | Avoid special symbols; use `-` instead of `→` |
|
|
808
|
+
|
|
809
|
+
### Example: Complex Inline SVG
|
|
810
|
+
|
|
811
|
+
```html
|
|
812
|
+
<div style="text-align: center; margin: 20px 0;"><svg width="600" height="400" viewBox="0 0 600 400" xmlns="http://www.w3.org/2000/svg" style="display: block; margin: 0 auto; background: #f5f5f5; border-radius: 12px;"><defs><linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#4A90E2;stop-opacity:1"/><stop offset="100%" style="stop-color:#357ABD;stop-opacity:1"/></linearGradient><linearGradient id="grad2" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" style="stop-color:#7ED321;stop-opacity:1"/><stop offset="100%" style="stop-color:#5DB80D;stop-opacity:1"/></linearGradient></defs><rect width="600" height="400" fill="#f5f5f5" rx="12"/><rect x="40" y="40" width="520" height="60" rx="8" fill="url(#grad1)"/><text x="300" y="78" fill="white" text-anchor="middle" font-size="22" font-weight="bold">Inline SVG Example</text><circle cx="150" cy="180" r="50" fill="url(#grad1)"/><text x="150" y="188" fill="white" text-anchor="middle" font-size="16" font-weight="bold">Node A</text><rect x="250" y="130" width="100" height="100" rx="10" fill="url(#grad2)"/><text x="300" y="185" fill="white" text-anchor="middle" font-size="16" font-weight="bold">Node B</text><polygon points="450,130 500,180 450,230 400,180" fill="#E74C3C"/><text x="450" y="188" fill="white" text-anchor="middle" font-size="14" font-weight="bold">Node C</text><line x1="200" y1="180" x2="250" y2="180" stroke="#666" stroke-width="2" stroke-dasharray="5,5"/><line x1="350" y1="180" x2="400" y2="180" stroke="#666" stroke-width="2" stroke-dasharray="5,5"/><rect x="100" y="280" width="400" height="80" rx="8" fill="white" stroke="#ddd" stroke-width="1"/><text x="300" y="310" fill="#333" text-anchor="middle" font-size="14" font-weight="bold">Three-Layer Rocket Model</text><text x="300" y="335" fill="#666" text-anchor="middle" font-size="12">Material - Manufacturing - Platform</text></svg><p style="font-size: 10pt; color: #666; margin-top: 12px;">Figure: Complex inline SVG example (single-line compressed format)</p></div>
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Comparison: Inline vs External SVG
|
|
816
|
+
|
|
817
|
+
| Feature | Inline SVG | External SVG |
|
|
818
|
+
|---------|-----------|--------------|
|
|
819
|
+
| **Use case** | Demo, learning, simple icons | Production environment, complex graphics |
|
|
820
|
+
| **Code location** | Inside Markdown file | Independent `.svg` file |
|
|
821
|
+
| **Format requirement** | 🔴 **Must be single-line compressed** | No special requirements |
|
|
822
|
+
| **Maintainability** | ⚠️ Difficult (long lines hard to read) | ✅ Excellent (independent files) |
|
|
823
|
+
| **Complexity limit** | Limited by single-line length | Unlimited |
|
|
824
|
+
| **Browser cache** | ❌ Cannot be cached | ✅ Auto-cached |
|
|
825
|
+
|
|
826
|
+
### Best Practices
|
|
827
|
+
|
|
828
|
+
#### When to Use Inline SVG:
|
|
829
|
+
- ✅ Demonstrations and learning purposes
|
|
830
|
+
- ✅ Simple icons (< 10 elements)
|
|
831
|
+
- ✅ Need single-file delivery
|
|
832
|
+
- ✅ Quick prototype development
|
|
833
|
+
|
|
834
|
+
#### When to Use External SVG:
|
|
835
|
+
- ✅ Production documents
|
|
836
|
+
- ✅ Complex graphics (> 20 elements)
|
|
837
|
+
- ✅ Need frequent editing and maintenance
|
|
838
|
+
- ✅ Team collaboration projects
|
|
839
|
+
|
|
840
|
+
### Maintenance Tips
|
|
841
|
+
|
|
842
|
+
1. **Use temporary line breaks during editing**
|
|
843
|
+
```html
|
|
844
|
+
<!-- Development phase: readable format -->
|
|
845
|
+
<svg ...>
|
|
846
|
+
<rect .../>
|
|
847
|
+
<circle .../>
|
|
848
|
+
</svg>
|
|
849
|
+
|
|
850
|
+
<!-- Before saving: compress to one line -->
|
|
851
|
+
<svg ...><rect .../><circle .../></svg>
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
2. **Use editor's "Join Lines" feature**
|
|
855
|
+
- VS Code: `Ctrl+J` (Windows) / `Cmd+J` (Mac)
|
|
856
|
+
- WebStorm: `Ctrl+Shift+J`
|
|
857
|
+
|
|
858
|
+
3. **Version control friendly**
|
|
859
|
+
- Git diff shows entire line changes
|
|
860
|
+
- Consider using `.gitattributes` for long-line handling
|
|
861
|
+
|
|
862
|
+
---
|
|
863
|
+
|
|
468
864
|
## Acknowledgments & Copyright
|
|
469
865
|
|
|
470
866
|
### Original Project
|