A Markdown editor and viewer for GNUstep on Linux, implemented in Objective-C using only GPL/LGPL-compatible C and Objective-C libraries.
- Phase 1 — Core:
NSDocument-based file handling,NSTextVieweditor, basic preferences (NSUserDefaults). - Phase 2 — Markdown: Integration with libmarkdown (Discount) to convert Markdown to HTML (optional; falls back to
<pre>-escaped text). - Phase 3 — Preview: Split view with editor and preview pane; full HTML rendering via WebKitGTK when available (auto-detected), including dark mode through a WebKit user style sheet.
- Phase 4 — Syntax highlighting: Custom
NSTextStoragewithNSRegularExpressionfor headings, bold/italic, inline and fenced code blocks, links, lists. - Phase 5 — Spell checking: GNU Aspell integration (auto-detected) wired into
NSTextView's spell pipeline, with an Ignore context menu on right-click of a marked word. - Phase 6 — Preferences: Font selection, theme (light/dark), preview refresh behavior, spell-check options.
- Phase 7 — Extras: Export to HTML/PDF/ODT (plus "Export a Copy…"), Print (⌘P), an outline view of headings, and tabs for multiple documents.
- File watching (Linux): the open file is watched via inotify; external changes debounce-reload the editor and preview. Clean documents reload automatically; dirty documents get a Reload / Keep prompt.
| Purpose | Library | License | Notes |
|---|---|---|---|
| Markdown parsing | Discount (libmarkdown) | BSD | Auto-detected at build |
| HTML preview | WebKitGTK | LGPL | Auto-detected at build |
| Spell checking | Aspell | LGPL | Auto-detected at build |
| ODT export | libzip | BSD | Auto-detected at build |
| File watching | inotify | (kernel) | Linux only |
| Syntax highlighting | Custom Obj-C | Your choice | In-tree |
- GNUstep Make (gnustep-make), Base and GUI (gnustep-base, gnustep-gui)
- Optional: libmarkdown (Discount) — auto-detected; enables Markdown→HTML rendering
- Optional: Aspell (
libaspell-dev) — auto-detected; enables real spell checking - Optional: WebKitGTK (
libwebkit2gtk-4.1-dev) — auto-detected; enables the real HTML preview - Optional: libzip (
libzip-dev) — auto-detected; enables ODT export
- Build SmallStepLib first (used for app lifecycle):
cd ../SmallStepLib && make
- Build the app:
. /usr/share/GNUstep/Makefiles/GNUstep.sh # or your installation path make
WebKitGTK, Aspell, libzip and libmarkdown are detected automatically via
pkg-config (plus a few common fallback paths), so no manual flag changes are
needed:
- WebKitGTK →
HAVE_WEBKIT; the preview pane then embeds a realWebKitWebView. - Aspell →
HAVE_ASPELL;SMAspellSpellCheckerbacks the editor's spell pipeline. - libzip →
HAVE_LIBZIP;SMExportODTwrites real ODT archives. - libmarkdown (Discount) →
HAVE_MKDIO_H;MarkdownRendererconverts Markdown to real HTML.
Without these libraries the app still builds and runs: the preview falls back to
a plain-text pane, spell checking degrades to the stub checker, ODT export
is disabled, and MarkdownRenderer falls back to <pre>-escaped text.
Install the library (package name is libmarkdown2-dev on Debian/Ubuntu, or
build from Discount);
it is then auto-detected like WebKit/Aspell/libzip. The GNUmakefile probes
pkg-config libmarkdown and common mkdio.h locations (including Debian's
multiarch subdirectory), and links -lmarkdown — falling back to -ldiscount
where the library is installed as libdiscount (e.g. macOS/Homebrew).
./SmallMarkdown.app/SmallMarkdownOr open from the GNUstep menu. You can create new documents or open .md / .markdown files. Each open document becomes a tab in the shared window (labeled with the document name, kept in sync on Save As); the left pane lists headings from the current document — click one to jump to it in the editor.
Implementation status vs plan: see PLAN_REVIEW.md.
Build and run the unit and UI suites:
make testor manually:
make -C Tests CC=clang all
./Tests/obj/SmallMarkdownUnitTests
./Tests/obj/SmallMarkdownUITestsOn a headless machine use a virtual display, e.g. xvfb-run ./Tests/obj/SmallMarkdownUITests.
- Unit tests cover:
MarkdownRenderer(render/wrap, empty/nil input, theme),MarkdownTextStorage(replace, attributes, fenced-code highlighting),SMOutlineItem(heading parsing),SMDocument(content,dataOfType:,readFromData:),SMSpellChecker(enable/suggest/check). - UI tests verify the document window structure (tabbed window: outline table, editor, preview) and the preferences window.
Main.m,SMAppDelegate— application entry, preferences registration, and the menu (File: New/Open/Save/Save As, Export HTML/PDF/ODT, Export a Copy…, Print, Close; Edit: Check Spelling).SMDocument,SMWindowController— document and window; tabbed window with outline + editor + preview in a split view; inotify file watching; print viaNSPrintOperation.MarkdownRenderer— Markdown→HTML via libmarkdown (Discount), plus a cached HTML preview template with theme CSS.SMWebKitPreviewView— X11-embeddedWebKitWebViewpreview (whenHAVE_WEBKIT); dark mode via aWebKitUserStyleSheet.SMPreviewView— preview pane (plain-text fallback).MarkdownTextStorage— syntax highlighting in the editor.SMSpellChecker,SMAspellSpellChecker— Aspell-backedNSSpellCheckerreplacement with ignore-word support.SMOutlineItem— heading model for the outline pane.SMExportODT— ODT (libzip) exporter.SMPreferencesController— font, theme, preview refresh, spell-check options.
This project is under the GNU Affero General Public License v3 or later. See LICENSE.
Libraries used (Discount, Aspell, WebKitGTK, libzip) have their own licenses (BSD, LGPL, …) and are GPL/LGPL-compatible.