gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.29k stars 244 forks source link

Add custom markup language #188

Open gyscos opened 6 years ago

gyscos commented 6 years ago

In order to give styled string to a TextView, we can currently parse Markdown text, which only supports bold and italic effects.

It would be nice to have another markup language available, supporting:

We may take inspiration from existing languages like BBCode or others.

Possible languages:

\bold{Bold and \italic{italic} text!}
\color{red}{Red text! with \colorbox{#123456}{background color!}}
FreeFull commented 6 years ago

Would some sort of AST be an option, rather than necessarily having to parse a string?

matthiasbeyer commented 6 years ago

Maybe, instead of inventing another language, taking a list of tokens would be more sufficient. Or let the user provide a parser implementation. That would not result in another language, but let the user define. This could be helpful later for other use cases as well.

gyscos commented 6 years ago

The only thing a TextView really needs to display styled text is a StyledString. It can already be constructed manually if needed (this is what the example/markup.rs currently does).

For added convenience, we may want to add easier ways to create such StyledString. There are many options for that; it can be done directly in the user's application code, in a separate crate, and, for the most common cases, it can be included right in cursive.

The markdown parser is such a case. Note that this parser doesn't really use any internal type private to cursive, and could as easily have been implemented in a dedicated crate (cursive-markdown maybe?). It's only included in cursive for convenience.

As this issue mentions, markdown doesn't quite support all the options that StyledString does. Many use-cases for styled text involve short messages where creating a StyledString manually would be a bit too much of a hassle. Being able to generate such a styled string in an easy way (and markup text is one of the easiest ways to define a styled text) would greatly improve user experience when writing short messages or prototyping layouts.

Most markup languages work the same way: they associate attributes to spans of text by having attribute prefixes ([b], <b>, \bold{, *) and suffixes ([/b], </b>, }, *) around the desired span of text. In essence, the only difference is the choice of such start/end tokens, and the escape pattern (often simply backslash-based). We mostly pick familiar tokens because users are used to them and usually have tools to help write them.

To come back to manually-created StyledString, they are flattened: for the markdown string **Foo*bar*!**:

And creating the StyledString manually must follow this, and work by creating consecutive disjoint sections (which are not as comfortable to write manually). An improvement could be to take a tree as input, and output the flattened StyledString.

(Rewrote the comment to be clearer)