[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-76081":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":17,"compositeScore":19,"rankGlobal":9,"rankLanguage":9,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":9,"pushedAt":9,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},76081,"swift-markdown-engine","nodes-app\u002Fswift-markdown-engine","nodes-app","A native AppKit Markdown editor for macOS, built on TextKit 2 and bridged to SwiftUI.  ",null,"Swift",667,51,3,16,0,27,81,218,9.15,"Apache License 2.0",false,"main",true,[],"2026-06-12 02:03:39","\u003Cp align=\"center\">                                                                                               \n\u003Cimg width=\"128\" alt=\"MDE-iOS-Default-1024x1024@1x\" src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F88905708-9336-4cfe-8ce8-2be20866e89f\" \u002F>\n\u003C\u002Fp>\n\n\u003Ch1 align=\"center\">SwiftMarkdownEngine\u003C\u002Fh1>  \n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fswift.org\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSwift-5.9+-F05138?logo=swift&logoColor=white\" alt=\"Swift 5.9+\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fdeveloper.apple.com\u002Fmacos\u002F\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPlatforms-macOS%2014+-lightgrey\" alt=\"Platforms macOS 14+\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"LICENSE\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-Apache%202.0-yellow.svg\" alt=\"License: Apache 2.0\" \u002F>\u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fnodes-app\u002Fswift-markdown-engine\u002Factions\u002Fworkflows\u002Fci.yml\">\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002Fnodes-app\u002Fswift-markdown-engine\u002Factions\u002Fworkflows\u002Fci.yml\u002Fbadge.svg\" alt=\"CI\" \u002F>\u003C\u002Fa>\n\u003C\u002Fp>\n\n\n\n\u003Cvideo src=\"https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002Fb61ed622-0e9a-4e91-9de5-9cd6c53752e5\"\n       autoplay loop muted playsinline\n       width=\"100%\">\n\u003C\u002Fvideo>\n\n\nA native AppKit Markdown editor for macOS, built on TextKit 2 and bridged to\nSwiftUI. Live styling, wiki-link support, fenced code blocks with syntax\nhighlighting, LaTeX rendering, embedded images, and GitHub-style task\ncheckboxes.\n\n## Motivation\n\nWhen we started building **[Nodes](https:\u002F\u002Fnodes-web.com\u002F#\u002F)** a minimal, beautiful, and fast writing app for macOS, we thought the editor would be the easy part. We were wrong. None of the existing open-source options fit what we needed: a native editor we could drop straight into a Mac app. So we built it on top of TextKit 2. It [wasn't easy](https:\u002F\u002Fblog.krzyzanowskim.com\u002F2025\u002F08\u002F14\u002Ftextkit-2-the-promised-land\u002F), but the result holds up in production. We're sharing it because we wished something like this had existed when we started.\n\n## Features\n\n- **Live Markdown styling** — bold, italic, headings, lists, code, links,\n  task checkboxes, horizontal rules\n- **Wiki-style linking** with two-form storage \u002F display roundtripping\n  (`[[Name|\u003Cid>]]` ↔ `[[Name]]`)\n- **Image embeds** — `![[Name]]` syntax, embedder supplies the bytes\n- **LaTeX** — both block (`$$ … $$`) and inline (`$…$`), embedder supplies\n  the renderer\n- **Code blocks** with embedder-supplied syntax highlighting and overlayable\n  copy buttons\n- **TextKit 2** layout for accurate, modern text rendering\n- **Writing Tools** integration on macOS 15.1+\n- **Comfortable bottom overscroll** so the caret never pins to the viewport\n  edge while typing\n- **Drag-select autoscroll boost** for long documents\n- **Spelling & grammar** with code\u002FLaTeX\u002Fwiki-link suppression\n\n## Installation\n\n```swift\ndependencies: [\n    .package(url: \"https:\u002F\u002Fgithub.com\u002Fnodes-app\u002Fswift-markdown-engine\", from: \"0.1.0\")\n],\ntargets: [\n    .target(\n        name: \"YourApp\",\n        dependencies: [\n            .product(name: \"MarkdownEngine\", package: \"swift-markdown-engine\"),\n        ]\n    )\n]\n```\n\nOr in Xcode: **File → Add Package Dependencies…** and paste the repo URL.\n\nThe package ships three library products — add only what you need:\n\n| Product | Use when |\n|---|---|\n| `MarkdownEngine` | You want the editor only. Zero external dependencies. |\n| `MarkdownEngineCodeBlocks` | You want the full visual code-block experience — background fill, monospace font, and syntax highlighting — without writing your own bridge. Pulls in [HighlighterSwift](https:\u002F\u002Fgithub.com\u002Fsmittytone\u002FHighlighterSwift) transitively. See [Customization → Code Blocks](#code-blocks). |\n| `MarkdownEngineLatex` | You want LaTeX formula rendering without writing your own bridge. Pulls in [SwiftMath](https:\u002F\u002Fgithub.com\u002Fmgriebling\u002FSwiftMath) transitively. See [Customization → LaTeX Rendering](#latex-rendering). |\n\n## Quick Start\n\n```swift\nimport SwiftUI\nimport MarkdownEngine\n\nstruct EditorScreen: View {\n    @State private var text: String = \"# Hello, *world*\"\n\n    var body: some View {\n        NativeTextViewWrapper(text: $text)\n    }\n}\n```\n\nThat's it. See [Customization](#customization) below for syntax\nhighlighting, themes, wiki-link state, and more.\n\n> **Displaying multiple editors?** Pass a stable, unique\n> `documentId: \"your-doc-id\"` so undo history and pending replacements\n> stay scoped to each editor instance.\n\n## Customization\n\n### Service Protocols\n\nThe engine talks to your app through four service protocols, each with\na no-op default so you only implement what you actually need:\n\n| Protocol | What you supply | Ready-made bridge \u002F suggested library |\n|---|---|---|\n| `WikiLinkResolver` | Resolve a `[[Name]]` to a stable opaque id | (your data model) |\n| `EmbeddedImageProvider` | Look up an `NSImage` for `![[Name]]` | (your asset store) |\n| `SyntaxHighlighter` | Highlight code blocks for a given language | **`HighlighterSwiftBridge`** ([recommended](#code-blocks)) — built on [HighlighterSwift](https:\u002F\u002Fgithub.com\u002Fsmittytone\u002FHighlighterSwift) |\n| `LatexRenderer` | Render a LaTeX string to an `NSImage` | **`SwiftMathBridge`** ([recommended](#latex-rendering)) — built on [SwiftMath](https:\u002F\u002Fgithub.com\u002Fmgriebling\u002FSwiftMath) |\n\nImplement what you need and pass it through `MarkdownEditorServices`:\n\n```swift\nstruct MyResolver: WikiLinkResolver {\n    func resolve(displayName: String, range: NSRange) -> WikiLinkResolution? {\n        myIndex[displayName].map { WikiLinkResolution(id: $0, exists: true) }\n    }\n}\n\nconfiguration.services = MarkdownEditorServices(\n    wikiLinks: MyResolver()\n    \u002F\u002F images, syntaxHighlighter, latex omitted → no-op defaults\n)\n```\n\nEach protocol and its no-op default are documented in DocC.\n\n### Code Blocks\n\n**Recommended path: depend on the `MarkdownEngineCodeBlocks` product\nand use the bundled `HighlighterSwiftBridge`.** Rolling your own\n`SyntaxHighlighter` has subtle footguns the bridge already handles —\nline-height metrics across light\u002Fdark themes, appearance-change\nobservation, layout-pass timing, font name extraction from the theme,\nand CSS-theme-derived background colors. Use the bundle unless you\nspecifically need a non-HighlighterSwift library.\n\n```swift\nimport MarkdownEngineCodeBlocks\n\nvar configuration = MarkdownEditorConfiguration.default\nconfiguration.services = MarkdownEditorServices(\n    syntaxHighlighter: HighlighterSwiftBridge()\n)\n```\n\nThe bridge auto-switches between `atom-one-light` and `atom-one-dark`\nwith system appearance. Different theme names or a pinned single theme\nare configurable via init params — see DocC.\n\nNeed a different highlighter library entirely? Implement\n`SyntaxHighlighter` yourself (see [Service Protocols](#service-protocols)\nabove for the declaration) and reference the bundled bridge in\n`Sources\u002FMarkdownEngineCodeBlocks\u002F` as a working example.\n\n### LaTeX Rendering\n\n**Recommended path: depend on the `MarkdownEngineLatex` product and use\nthe bundled `SwiftMathBridge`.** Hand-rolling a `LatexRenderer` has\nreal footguns the bridge already handles — appearance-aware text color,\nzero-sized output guards (`lockFocus` crashes on 0×0 images),\nwindow-vs-NSApp appearance distinction, single-letter padding, and an\ninternal cache keyed by (latex, font size, appearance, theme color).\n\n```swift\nimport MarkdownEngineLatex\n\nvar configuration = MarkdownEditorConfiguration.default\nconfiguration.services = MarkdownEditorServices(\n    latex: SwiftMathBridge()\n)\n```\n\nThe bridge uses the Latin Modern math font and tints formulas with\n`MarkdownEditorTheme.latexLightModeText` \u002F `latexDarkModeText`. Pass\n`singleLetterPaddingBottom:` to override the engine's matching default.\n\n### Theming\n\nEvery color the editor puts on screen reads from `MarkdownEditorTheme`:\n\n```swift\nvar theme = MarkdownEditorTheme.default\ntheme.bodyText = .labelColor\ntheme.findMatchHighlight = NSColor(named: \"MyAccent\")!\n\nvar configuration = MarkdownEditorConfiguration.default\nconfiguration.theme = theme\n```\n\nDefaults map to `NSColor` dynamic system colors, so light\u002Fdark mode\nkeeps working without extra code.\n\n### Tuning\n\n`MarkdownEditorConfiguration` exposes every spacing \u002F sizing \u002F behavior\nknob the engine has, grouped by concern:\n\n```swift\nvar configuration = MarkdownEditorConfiguration.default\nconfiguration.codeBlock.fontSizeScale = 0.9\nconfiguration.headings.fontMultipliers = [2.4, 1.8, 1.4, 1.1, 0.9, 0.75]\nconfiguration.overscroll.percent = 0.4\nconfiguration.lists.helpersEnabled = false\n```\n\n### Wiki-Links & Replacement State\n\nTwo optional bindings on `NativeTextViewWrapper` let you observe\nwiki-link state and push inline replacements programmatically. Pass\nonly what you need — each is independent and defaults to a no-op:\n\n```swift\nNativeTextViewWrapper(\n    text: $text,\n    isWikiLinkActive: $isWikiLinkActive,\n    pendingInlineReplacement: $pendingReplacement\n)\n```\n\n- `isWikiLinkActive` — the wrapper sets this to `true` while the caret\n  sits inside a `[[Name]]` link, so you can present a contextual UI.\n- `pendingInlineReplacement` — assign a non-nil value to push a\n  replacement (e.g. an autocomplete result); the engine consumes it\n  and clears the binding.\n\n## Demo\n\nA runnable SwiftUI demo lives in [`Demo\u002F`](Demo\u002FMarkdownEngineDemo.xcodeproj).\nOpen it in Xcode and hit **Run** — the demo references the package via\na local path, so any engine edit rebuilds into the demo on the next run.\n\n> If you're seeing a \"missing package product\" error, it's almost always\n> stale package cache. Use **File → Packages → Reset Package Caches**\n> once and rebuild.\n\n## Documentation\n\nFull API documentation is available via DocC. In Xcode, use\n**Product → Build Documentation** (`⇧⌃⌘D`).\n\nFor local CLI preview, temporarily add the Swift DocC plugin as described in\n[CONTRIBUTING.md](CONTRIBUTING.md), then run:\n\n```bash\nswift package --disable-sandbox preview-documentation --target MarkdownEngine\n```\n\nOnce the package is hosted on Swift Package Index, the docs will live at\n`https:\u002F\u002Fswiftpackageindex.com\u002Fnodes-app\u002Fswift-markdown-engine\u002Fdocumentation`.\n\n## Requirements & Status\n\n- macOS 14 or later (15.1+ for Apple Writing Tools integration)\n- Swift 5.9 \u002F Xcode 15 or later\n\nMarkdownEngine is currently **pre-1.0**. The public API may change between\nminor releases as it stabilizes. Production use is fine — pin a specific\nversion (`0.x.y`) in your `Package.swift`.\n\n## Contributing\n\nBug reports, ideas, and pull requests are welcome.\n\n- [ARCHITECTURE.md](ARCHITECTURE.md) — codemap and pipeline guide for\n  contributors\n- [CONTRIBUTING.md](CONTRIBUTING.md) — setup, PR process, and design\n  constraints\n\n## License\n\nMarkdownEngine is released under the Apache 2.0 License. See [LICENSE](LICENSE)\nfor the full text.\n\n---\nBuilt by small team from Germany. Day-to-day on [Instagram](https:\u002F\u002Fwww.instagram.com\u002Fnodes.app).\n","SwiftMarkdownEngine 是一个专为 macOS 设计的原生 AppKit Markdown 编辑器，基于 TextKit 2 构建，并与 SwiftUI 桥接。其核心功能包括实时 Markdown 样式、Wiki 风格链接、LaTeX 渲染、代码块高亮显示以及图像嵌入等，提供了丰富的文本编辑体验。该项目利用了最新的 TextKit 2 技术来确保高质量的文字布局和渲染效果，同时集成了拼写与语法检查等功能以提升写作效率。它适用于需要在 macOS 应用程序中集成强大 Markdown 编辑能力的场景，特别是那些追求美观且高效写作环境的应用开发项目。",2,"2026-06-11 03:54:25","CREATED_QUERY"]