Introduction

Welcome! And thank you for checking out boustro 😎

What is boustro?

Boustro is a rich text editor for Flutter.

About the documentation

This documentation is a work in progress. Greyed out chapters in the navigation bar have not yet been written.

If you want to try out boustro, for now, the best way to get started is to check out the example.

This documentation is built with mdBook.

Goals

Boustro aims to be an easy to use, fully-featured, but extremely flexible rich text editor.

The following are goals for Boustro:

  • Pick and choose formatting and embed options.
  • Fully customizable without touching the source code.
  • Built-in formatting options and paragraph types for common use cases.
  • Beautiful default dark and light theme.
  • Built-in serialization that's easily extendable for custom paragraphs.

Model

This chapter describes how rich text content is represented in boustro. The terminology from this chapter is used throughout the book.

Document

A document in boustro is a list of lines of formatted text and embeddable content (called embeds). An immutable document is represented by a Document. While editing a document, its state is maintained by a DocumentController.

A document holds a collection of Paragraphs. Paragraphs are either a line of rich text — or an embed — which can be any custom content, for example an image or a code block.

Text

A text line represents rich text using a spanned string. Text lines can be modified with line modifiers. These modifiers wrap a line of text and can modify how they are displayed or override their style. Boustro has a modifier for bullet lists.

Spanned strings hold text, along with a list of spans that apply formatting or attach gestures to the text. The mutable version of a SpannedString is a SpannedTextEditingController — a subclass of Flutter's TextEditingController that manages formatting of its text.

Both SpannedString and SpannedTextEditingController maintain a SpanList. SpanList is an immutable list of AttributeSpan.

Attribute spans hold an attribute and a range:

  • Range: range in the source text to which the attribute is applied. The boundaries of the range are indices into the source text, using Unicode (Extended) Grapheme Clusters (EGC) as the unit. EGC map to user-perceived characters. EGC indices are used to prevent indices in the middle of user-perceived characters. If you use a Range directly, you likely want to use the characters package.
  • TextAttribute: The attribute can be resolved to a TextStyle (to apply formatting) and gestures (for example tap handler that opens a hyperlink) with its resolve method, which can optionally use an AttributeTheme to resolve to a style and gestures. The attribute also defines SpanExpandRules which determine how the span responds to insertions in the source text.

Embeds

An embed, in boustro, is a custom piece of content that can be embedded in rich text.

Visually, an embed can be any widget, and users can define different widgets for the editable and view-only version of the embed.

See Embeds to learn how embeds work and how to create custom embeds.

Component

A component is any implementation of TextAttribute, LineModifier or ParagraphEmbed. This concept is not used within boustro itself, but it's useful to define it for talking about customization in boustro.

Customization

Boustro is designed to be extremely customizable.

To learn how to:

Built-in components

Boustro — the rich text editor itself — does not know how to apply .

Boustro uses abstractions to make it as extensible1 as possible. Any text attributes and paragraphs2 can be defined in user code.

Boustro provides a range of built-in components that are commonly required in a rich text editor. Here, you'll find a list of components provided.

Attributes

  • Bold
  • Italic
  • Underline
  • Strikethrough
  • Link (with user-defined callback)

Paragraphs

  • Bullet list (TODO)
  • Numbered list (TODO)
  • Blockquote (TODO)
  • Image
  • Code block (TODO)

If you're missing a component that is generally useful, please open an issue to request it.

2

For an explanation of these concepts, see Model.

1

See Customization for more information about the different ways in which boustro can be customized.

boustro Changelog

0.2.0

  • Changed: Merged boustro_starter and flutter_spanned_controller into boustro for easier consumption and development. You can find the old changelogs for those packages in the history of the Git repository.
  • Changed: Boustro now uses marker characters to detect backspace on empty lines. See this blog post for an explanation on why that's necessary. It uses space characters so capitalization on iOS works properly. They are replaced with zero-width spaces when rendered.
  • Added: BoustroScaffold widget that provies a default layout and maintains editor focus when clicking the toolbar.
  • Added: Link toolbar item support for custom validator and input processor.
  • Fixed: Link toolbar item URI's does not prepend https:// for URI's that contain a protocol.

0.1.1

  • Added textSelectable flag to DocumentView.

0.1.0

Initial publish.

Package (pub.dev)

API reference

Contribute to boustro

Boustro is still a very young project that I'm developing for my own (proprietary) app. I do, however, wish for boustro to become a great solution for anyone requiring rich text editing capabilities in their Flutter app.

Bug fixes or small improvements are welcome. For design discussions or feature requests, please open an issue.