Kotoba.Features (Kotoba v0.8.0)

Copy Markdown View Source

The built-in features of the editor, and the check of a document against the features of a field.

Kotoba.Components.kotoba/1 takes a features list: the editor has those features, and no other. With no list, it has every feature but blocks, which an editor has only when its list names it (features={Kotoba.Features.all()} gives every one).

<.kotoba field={@form[:comment]} features={~w(bold italic links lists mentions)} />
FeatureWhat it isNodes and formats
boldbold textthe bold format
italicitalic textthe italic format
underlineunderlined textthe underline format
strikethroughstruck textthe strikethrough format
highlighthighlighted text, and the color palettethe highlight format, a text color
subscriptsubscript text (not in the default toolbar)the subscript format
superscriptsuperscript text (not in the default toolbar)the superscript format
inline_codecode in a line of textthe code format
linkslinks, autolinks, the link formlink, autolink
headingsheadingsheading
quotesblock quotesquote
listsbulleted and numbered listslist, listitem
check_listscheck lists (needs lists)a list with listType "check"
code_blockscode blocks and their language pickercode, code-highlight
horizontal_ruleshorizontal ruleshorizontalrule
tablestablestable, tablerow, tablecell
attachmentsfile uploads and image galleries (with the uploads attribute)attachment, gallery
mentionsprompts and mentions (with the prompts attribute)mention
imagesimages from a URL, as Markdown has themimage
footnotesfootnotes and their referencesfootnotedefinition, footnotereference
embedslive things of the app's own, as a canvas (with Kotoba.Embeds)embed
blocksa handle beside each block: drag it to move the block, click it for the block's menu (only when listed)none

Paragraphs, line breaks, tabs, undo and redo are always there. The case formats (lowercase, uppercase, capitalize) are not features: the editor keeps them.

The keyboard shortcuts of the formats are Cmd (Ctrl on other systems) with B, I, U, Shift+H (highlight), , (subscript) and . (superscript). Subscript and superscript have no button in the default toolbar: an app's toolbar (Kotoba.Components.kotoba_toolbar/1) can have them.

A feature that is off has no node, no toolbar button, no Markdown shortcut and no keyboard shortcut in the editor. A pasted table, heading or code block comes in as paragraphs, and a pasted format that is off is dropped. A stored node of a feature that is off loads as an unknown node: the editor shows a placeholder and saves it with no change.

The Editing features guide has the shortcuts and the toolbar of each feature.

The editor is not a check: a request can post any document. To refuse a document with a feature that the field does not have, use Kotoba.Content.validate_features/3 in the changeset, or check/2. App nodes and unknown nodes are not features, and check/2 allows them.

Summary

Types

A built-in feature.

Functions

Returns the features, in order.

Checks that a document uses only the given features (a list for names!/1). Returns :ok, or {:error, features} with the features that it uses and does not have.

Returns the features of a list of names (atoms or strings), in the order of all/0 and once each.

Returns the features that a document uses, in the order of all/0.

Types

feature()

@type feature() ::
  :bold
  | :italic
  | :underline
  | :strikethrough
  | :highlight
  | :subscript
  | :superscript
  | :inline_code
  | :links
  | :headings
  | :quotes
  | :lists
  | :check_lists
  | :code_blocks
  | :horizontal_rules
  | :tables
  | :attachments
  | :mentions
  | :images
  | :footnotes
  | :embeds
  | :blocks

A built-in feature.

Functions

all()

@spec all() :: [feature()]

Returns the features, in order.

Examples

iex> :tables in Kotoba.Features.all()
true

check(doc, features)

@spec check(Kotoba.Document.t(), [atom() | String.t()]) :: :ok | {:error, [feature()]}

Checks that a document uses only the given features (a list for names!/1). Returns :ok, or {:error, features} with the features that it uses and does not have.

Examples

iex> {:ok, doc} =
...>   Kotoba.Document.parse(%{
...>     "kotoba" => 1,
...>     "lexical" => "0.51",
...>     "root" => %{"type" => "root", "children" => [%{"type" => "quote", "children" => []}]}
...>   })
iex> Kotoba.Features.check(doc, [:bold])
{:error, [:quotes]}
iex> Kotoba.Features.check(doc, [:quotes])
:ok

names!(names)

@spec names!([atom() | String.t()]) :: [feature()]

Returns the features of a list of names (atoms or strings), in the order of all/0 and once each.

Raises ArgumentError for a name that is not a feature, or for a feature without the one that it needs (check_lists needs lists).

Examples

iex> Kotoba.Features.names!(["lists", :bold, "lists"])
[:bold, :lists]

used(doc)

@spec used(Kotoba.Document.t()) :: [feature()]

Returns the features that a document uses, in the order of all/0.

Examples

iex> {:ok, doc} =
...>   Kotoba.Document.parse(%{
...>     "kotoba" => 1,
...>     "lexical" => "0.51",
...>     "root" => %{
...>       "type" => "root",
...>       "children" => [
...>         %{"type" => "heading", "tag" => "h2", "children" => [%{"type" => "text", "text" => "Hi", "format" => 1}]}
...>       ]
...>     }
...>   })
iex> Kotoba.Features.used(doc)
[:bold, :headings]