InkPond
A native iOS/iPadOS editor for Typst — the modern typesetting system.
Install / Use
/learn @Lin0u0/InkPondREADME
InkPond
InkPond (墨池) is a native iOS/iPadOS editor for Typst, with live preview and PDF export powered by a Rust FFI bridge.
<p align="center"> <a href="https://testflight.apple.com/join/w5jmkR2T"><img src="https://img.shields.io/badge/TestFlight-Beta-0D96F6?logo=apple&logoColor=white" alt="TestFlight"></a> <a href="README.zh-CN.md"><img src="https://img.shields.io/badge/中文文档-README.zh--CN-34A853" alt="Chinese README"></a> </p> <p align="center"> <img src="https://img.shields.io/badge/Platform-iOS%2017%2B%20%26%20iPadOS%2017%2B-2563EB" alt="Platform"> <img src="https://img.shields.io/badge/Language-Swift%205-F59E0B" alt="Language"> <img src="https://img.shields.io/badge/Typst-0.14.2-0EA5A4" alt="Typst Version"> <img src="https://img.shields.io/badge/License-Apache%202-1D4ED8" alt="License"> </p>Languages
- English (current)
- 简体中文: README.zh-CN.md
Quick Actions
| Action | Command / Link |
|---|---|
| Join beta | testflight.apple.com/join/w5jmkR2T |
| Build Rust FFI | cd rust-ffi && ./build-ios.sh |
| Simulator debug build | xcodebuild -project InkPond.xcodeproj -scheme InkPond -configuration Debug -destination 'generic/platform=iOS Simulator' build |
| Export options file | release/ExportOptions.plist |
Features
Editor
- Syntax highlighting with 15 rules, rainbow bracket coloring, and bracket mismatch detection
- Auto-pairing for
{}[]()""$$with smart type-over, auto-delete, and auto-indent - Code completion for Typst functions (~150), keywords, font families, labels, references, and image paths
- Snippets library with custom templates and
$0cursor placeholders - Find and replace (system
UIFindInteraction) - Line number gutter with error line highlighting
- Keyboard accessory bar with quick-insert buttons
Preview
- Live PDF preview with debounced recompilation (350ms)
- Bidirectional editor-to-preview sync via source maps
- Document statistics (pages, words/tokens, characters; CJK-aware)
- Error banner with source location links
- Full-screen slideshow mode
- Outline view for heading navigation
Project Management
- Multi-file projects with customizable entry file
- Project file browser with .typ, image, and font sections
- Image import from Photos, clipboard (including HTML paste), and remote URLs
- Per-project and app-wide font management (bundled CJK fallback included)
- ZIP project import and export
- PDF and source (.typ) export
UI/UX
- Adaptive layout: split view on iPad, tabbed on iPhone
- Three editor themes: Mocha (dark), Latte (light), System (adaptive) — based on Catppuccin
- Onboarding flow for new users
- Editor position resumption across launches
- Full VoiceOver and accessibility support
- Localized in English, Simplified Chinese, Traditional Chinese (HK/TW)
- iOS 26 enhancements where available, with iOS 17-compatible fallbacks
Requirements
- macOS with Xcode 26.3+
- iOS/iPadOS deployment target: 17.0 (app target)
- Rust toolchain (
rustup,cargo) for buildingtypst_ios.xcframework
Quick Start
- Clone repo:
git clone <your-fork-or-origin-url> cd InkPond - Make sure the native toolchain is ready:
If any of these fail, install Xcode command line tools and the Rust toolchain before continuing.xcode-select -p cargo --version rustup show - Build the Rust FFI framework:
This generatescd rust-ffi ./build-ios.sh cd ..Frameworks/typst_ios.xcframework, which is not committed to git. - Build and run in Xcode:
open InkPond.xcodeproj
Build Commands
# Simulator debug build
xcodebuild -project InkPond.xcodeproj -scheme InkPond -configuration Debug -destination 'generic/platform=iOS Simulator' build
# Device release archive
xcodebuild -project InkPond.xcodeproj -scheme InkPond -configuration Release -destination 'generic/platform=iOS' archive
# Tests
xcodebuild test -project InkPond.xcodeproj -scheme InkPond -destination 'platform=iOS Simulator,name=iPhone 17,OS=26.2'
# If your local simulator list differs, inspect available destinations first:
# xcodebuild -showdestinations -project InkPond.xcodeproj -scheme InkPond
Rust FFI Notes
Frameworks/typst_ios.xcframeworkis generated byrust-ffi/build-ios.sh.rust-ffi/build-ios.shremovesrust-ffi/target/after packaging the xcframework to minimize local disk usage.Frameworks/typst_ios.xcframework/is a local build artifact and is ignored by git.- Re-run
rust-ffi/build-ios.shwhen:- updating Typst / Rust dependencies
- changing
rust-ffi/src/lib.rs - rebuilding release artifacts for distribution
- If Xcode shows
Typst compiler library not linked, the xcframework is missing, stale, or was built before switching branches. Re-run the build script and rebuild the app.
Current pinned Typst version: 0.14.2 (see rust-ffi/Cargo.toml).
Release Pipeline (CLI)
Typical flow:
# 1) Archive
xcodebuild -project InkPond.xcodeproj -scheme InkPond -configuration Release -destination 'generic/platform=iOS' -archivePath /private/tmp/InkPond.xcarchive archive
# 2) Export IPA (using your ExportOptions.plist)
xcodebuild -exportArchive -archivePath /private/tmp/InkPond.xcarchive -exportPath /private/tmp/InkPond-export -exportOptionsPlist release/ExportOptions.plist
# 3) Upload (example app id)
asc --profile default builds upload --app 6760032537 --ipa /private/tmp/InkPond-export/InkPond.ipa --output table
After upload, wait for processing, then distribute build to TestFlight groups.
Project Layout
InkPond/
├── InkPond/
│ ├── InkPondApp.swift # @main entry point, SwiftData ModelContainer
│ ├── ContentView.swift # NavigationSplitView shell, environment setup
│ ├── Models/
│ │ └── InkPondDocument.swift # @Model: document data + project config
│ ├── Editor/
│ │ ├── TypstTextView.swift # UITextView subclass (TextKit 1)
│ │ ├── SyntaxHighlighter.swift # 15-rule highlighting + rainbow brackets
│ │ ├── CompletionEngine.swift # Context-aware code completion
│ │ ├── AutoPairEngine.swift # Bracket/quote auto-pairing
│ │ ├── SyncCoordinator.swift # Bidirectional editor↔preview sync
│ │ ├── EditorTheme.swift # Mocha/Latte/System theme definitions
│ │ ├── ThemeManager.swift # Theme persistence (UserDefaults)
│ │ ├── Snippet*.swift # Snippet model, library, and store
│ │ ├── HighlightScheduler.swift # Debounced highlighting
│ │ ├── LineNumberGutterView.swift # Gutter with error markers
│ │ └── KeyboardAccessoryView.swift # Accessory bar (photo/snippet buttons)
│ ├── Compiler/
│ │ ├── TypstBridge.swift # Rust FFI wrapper (compile + source map)
│ │ ├── TypstCompiler.swift # Debounced compilation pipeline + cache
│ │ ├── SourceMap.swift # Line↔page bidirectional mapping
│ │ ├── ProjectFileManager.swift # Per-project file CRUD + validation
│ │ ├── FontManager.swift # Bundled CJK + project + app font resolution
│ │ ├── ExportManager.swift # PDF/source/ZIP export (custom ZIP writer)
│ │ ├── ExportController.swift # Export UI state machine
│ │ ├── ZipImporter.swift # ZIP project import
│ │ ├── DirectoryMonitor.swift # DispatchSource file system watcher
│ │ └── *CacheStore.swift # Compiled preview + package caches
│ ├── Views/
│ │ ├── DocumentList/ # Document library, search, sort, rename
│ │ ├── DocumentEditor/ # Editor/preview split, file ops, images
│ │ │ └── OutlineView.swift # Heading outline navigation
│ │ ├── EditorView.swift # UIViewRepresentable for TypstTextView
│ │ ├── PreviewPane.swift # PDFKit live preview + stats + sync marker
│ │ ├── SlideshowView.swift # Full-screen PDF presentation
│ │ ├── OnboardingView.swift # First-launch onboarding
│ │ ├── SnippetBrowserSheet.swift # Snippet library browser
│ │ ├── ProjectFileBrowserSheet.swift
│ │ ├── ProjectSettingsSheet.swift
│ │ └── Settings/ # App settings, fonts, cache, shortcuts
│ ├── Localization/ # L10n.swift + .strings (en, zh-Hans, zh-Hant)
│ ├── Storage/
│ │ └── AppFontLibrary.swift # App-wide font import tracking
│ ├── Shared/UI/ # UIKit/SwiftUI bridges, haptics, a11y
│ └── Bridging/ # typst_ffi.h bridging header
├── rust-ffi/
│ ├── src/lib.rs # Rust Typst wrapper
│ ├── Cargo.toml # Rust dependencies (Typst engine)
│ └── build-ios.sh # XCFramework build (device + sim)
├── Frameworks/
│ └── typst_ios.xcframework/ # Generated build artifact (not committed)
├── release/
│ └── ExportOptions.plist
└── InkPond.xcodeproj
Troubleshooting
Typst compiler library not linked:- Run
cd rust-ffi && ./build-ios.shand rebuild the app. - If the script fails immediately, check
cargo --version,rustup show, andxcode-select -p. - If the script succeeds but Xcode still fails to link, clean the build folder and rerun the app build.
- Run
- Simulator link errors about
typst_iosarchitecture:- Rebuild xcframework; the script generates
arm64 + x86_64simulator slices.
- Rebuild xcframework; the script generates
- TestFlight upload succeeded but not distributable yet:
- Build is still processing in App Store Connect.
Acknowledgements
- Typst - core typesetting engine used for rendering and PDF generation (Apache 2.0)
- Catppuccin - color system used by the editor themes (MIT)
- Source Han Sans / [Source Han Serif](https:/
Related Skills
node-connect
342.5kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
85.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
342.5kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
342.5kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
