bdewey/TextMarkupKit
Pure-Swift tools for understanding and editing text files with simple markup
Installation
Install TextMarkupKit using Swift Package Manager.
dependencies: [
.package(url: "https://github.com/bdewey/TextMarkupKit", from: "0.7.0"),
],
Please note that TextMarkupKit is not yet at Version 1.0.0 -- the API is changing frequently and dramatically as I adopt code written for one specific application for general use.
Using TextMarkupKit -- the absolute basics
While TextMarkupKit is designed to support custom formatting and custom markup languages, you can get started with a subset of Markdown out-of-the box. Using UIKit:
import TextMarkupKit
import UIKit
// textStorage will hold the characters and formatting (determined by the markup rules).
//
// MiniMarkdownGrammar.defaultEditingStyle():
// - Tells `ParsedAttributedString` to use the rules of MiniMarkdownGrammar to parse the text
// - Provides a default set of formatters to style the parsed text.
let textStorage = ParsedAttributedString(string: "# Hello, world!\n", style: MiniMarkdownGrammar.defaultEditingStyle())
// MarkupFormattingTextView is a subclass of UITextView and you can use it anywhere you would use a UITextView.
let textView = MarkupFormattingTextView(parsedAttributedString: textStorage)Using SwiftUI:
import SwiftUI
import TextMarkupKit
struct ContentView: View {
@Binding var document: TextMarkupKitSampleDocument
var body: some View {
// `MarkupFormattedTextEditor` is a SwiftUI wrapper around `MarkupFormattingTextView` that commits its changes back to the
// text binding when editing is complete. By default it uses `MiniMarkdownGrammar.defaultEditingStyle()`, but you can provide
// a custom style with the `style:` parameter.
MarkupFormattedTextEditor(text: $document.text)
}
}That's it! You now have a view that will format plain text and automatically adjust as the content changes. Check out the sample application to see this in action.
[TextMarkupKit Sample App]
Further Reading
Since this project started for personal use, documentation is sparse. While I build it up, this is an overview of the important areas of code.
Parsing
ParsingRuleis an abstract base class. The job of a parsing rule is to evaluate the input text at specific offset and produce aParsingResult, which is a struct that indicates:
- If the parsing rule succeeded at that location - If the rule succeeded, how much of the input string is consumed by the rule. Parsing continues after the consumed input. - How much of the input string the ParsingRule had to look at at to make its success/fail decision.
PackratGrammaris a protocol something that defines a complete grammar through a graph ofParsingRules.PackratGrammarexposes a single rule,start, that will be used when attempting to parse a string.MemoizationTableimplements the core incremental packrat parsing algorithm.
Additionally, ParsingRule.swift defines many simple rules that you can combine to build much more complex rules for constructing your grammar.
DotRulematches any character.Charactersmatches any character defined by aCharacterSet.Literalmatches a string literal.InOrdertakes an array of child rules and succeeds if every one of the child rules succeeds in sequence.Choicealso takes an array of child rules, but matches the first of the child rules in the array.AssertionRuletakes a single child rule. It succeeds if its child rule succeeds but it does not consume the input.NotAssertionRule, likeAssertionRule, takes a single child rule. It will succeed if its child rule fails and vice versa, and never consumes input.RangeRuletakes a single child rule and will try repeatedly match the rule to the input. It succeeds if the number of successful repetitions of the child rule falls within a specified range.
TextStorage
PieceTableimplements the piece table data structure for efficient text editing.PieceTableStringis a subclass ofNSMutableStringthat uses aPieceTablefor its internal storage.ParsedAttributedStringis a subclass ofNSMutableAttributedStringthat:
1. Uses a PieceTableString for character storage; 2. Uses a MemoizationTable to parse the string and incrementally re-parse the string on each change; 3. Applies a set of formatting rules based upon the parsed syntax tree to determine the formatting of the string.
ObjectiveCTextStorageWrapperis anNSTextStorageimplementation that lets you use aParsedAttributedStringas the backing storage forTextKit, likeUITextView.
Package Metadata
Repository: bdewey/TextMarkupKit
Stars: 25
Forks: 2
Open issues: 1
Default branch: master
Primary language: swift
License: Apache-2.0
README: README.md