Skip to content

Commit 85996f4

Browse files
committed
2 parents f571329 + 91b4d3f commit 85996f4

3 files changed

Lines changed: 174 additions & 0 deletions

File tree

docs/.vitepress/config/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ function sidebarGuide() {
9797
{ text: "What is MMRL", link: "/guide/" },
9898
{ text: "How a Module Card Works", link: "/guide/how-a-module-card-works" },
9999
{ text: "Anti-Features", link: "/guide/antifeatures" },
100+
{ text: "Text Formatting", link: "/guide/text-formatting" },
100101
{ text: "Installer API", link: "/guide/installer" },
101102
{ text: "FAQ", link: "/guide/faq" },
102103
],

docs/en/guide/text-formatting.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Text Formatting
2+
3+
This document describes a custom text formatting syntax used in both shell scripts, module configuration files, and Jetpack Compose UI development. This syntax allows you to add color and style to your text output using simple tags.
4+
5+
## Overview
6+
7+
The formatting system uses tags enclosed in square brackets `[]` to define styles. These tags can control text color, background color, and text attributes like bold, italic, and underline.
8+
9+
## Supported Tags
10+
11+
The following tags are supported:
12+
13+
- **`[color=<value>]` / `[color]`**:
14+
15+
- Sets the foreground color of the text.
16+
- `<value>` can be a predefined color name (see [Supported Colors](#supported-colors) below).
17+
- Using `[color]` without a value (or with an unrecognized value) typically resets the color to the default or `Color.Unspecified` in Compose.
18+
19+
- **`[bg=<value>]` / `[bg]`**:
20+
21+
- Sets the background color of the text.
22+
- `<value>` can be a predefined color name (see [Supported Colors](#supported-colors) below).
23+
- Using `[bg]` without a value (or with an unrecognized value) typically resets the background color to the default or `Color.Unspecified` in Compose.
24+
25+
- **`[bold]`**:
26+
27+
- Applies bold styling to the text.
28+
- In Compose, this sets `FontWeight.Bold`.
29+
- In the shell script, this tag is stripped if `MMRL` is not "true". To actually render bold in a terminal, you'd typically need ANSI escape codes, which this script doesn't explicitly add (it only strips the custom tags).
30+
31+
- **`[italic]`**:
32+
33+
- Applies italic styling to the text.
34+
- In Compose, this sets `FontStyle.Italic`.
35+
- In the shell script, this tag is stripped if `MMRL` is not "true".
36+
37+
- **`[underline]`**:
38+
- Applies underline styling to the text.
39+
- In Compose, this sets `TextDecoration.Underline`.
40+
- In the shell script, this tag is stripped if `MMRL` is not "true".
41+
42+
## Usage
43+
44+
### Shell Script (`echo` function)
45+
46+
The provided `echo` shell function processes these tags:
47+
48+
```shell
49+
echo() {
50+
local msg="$*"
51+
if [ "$MMRL" = "true" ]; then
52+
command echo "$msg"
53+
else
54+
# Remove all custom formatting tags before printing
55+
command echo "$msg" | sed -E 's/\[(color|bg|bold|italic|underline)(=[^]]+)?]//g'
56+
fi
57+
}
58+
```
59+
60+
**Behavior (Shell Script):**
61+
62+
- If the environment variable `MMRL` is set to `"true"`, the `echo` command will print the message as-is, including all formatting tags. This might be useful for debugging or for systems that can interpret these tags directly.
63+
- If `MMRL` is not set to `"true"` (or is set to any other value), the function strips out all custom formatting tags using `sed` before printing the message. The output will be plain text.
64+
65+
**Example (Shell Script):**
66+
67+
```shell
68+
# With MMRL not "true" (default behavior)
69+
echo "This is a [color=red]red[color] message with [bold]bold text[bold]."
70+
# Output: This is a red message with bold text.
71+
72+
# With MMRL="true"
73+
MMRL="true" echo "This is a [color=red]red[color] message with [bold]bold text[bold]."
74+
# Output: This is a [color=red]red[color] message with [bold]bold text[bold].
75+
```
76+
77+
### Module Config (`config.json` in module root)
78+
79+
The custom formatting tags can be used within the `description` field of a module's `config.json` file.
80+
81+
**Note:** Only the `description` field supports this formatting API. It cannot be used with other fields like those in `module.prop`.
82+
83+
```json
84+
{
85+
"name": {
86+
"en": "Systemless module",
87+
"de": "Systemloses Modul"
88+
},
89+
"description": {
90+
"en": "[bg=red]Hello[bg], [color=primary]World[color]!",
91+
"de": "Hallo, [color=green]Welt[color]!"
92+
}
93+
}
94+
```
95+
96+
When an application (like a module manager that supports this format) reads this `config.json`, it would be responsible for parsing the `description` string and rendering the formatted text in its UI, likely using a mechanism similar to the Jetpack Compose `toStyleMarkup()` function.
97+
98+
### Jetpack Compose (`String.toStyleMarkup()`)
99+
100+
The Kotlin extension function `toStyleMarkup()` converts a string containing these formatting tags into an `AnnotatedString`, which can be used to display styled text in Jetpack Compose.
101+
102+
```kotlin
103+
// Simplified conceptual usage
104+
@Composable
105+
fun MyStyledText(text: String) {
106+
Text(text = text.toStyleMarkup())
107+
}
108+
109+
// Example
110+
MyStyledText(text = "Hello [color=blue]Blue World[color] with [bg=yellow]yellow background[bg] and [bold]bold[bold] text!")
111+
```
112+
113+
This will render "Hello " in the default style, "Blue World" in blue, " with " in default style, "yellow background" with a yellow background, " and " in default style, and "bold" in bold text. The styling is cumulative within the parsed segments.
114+
115+
## Supported Colors
116+
117+
The `colorFromName` Composable function in Kotlin defines the mapping from color names to `Color` objects. These names can be used in `[color=<name>]` and `[bg=<name>]` tags.
118+
119+
| Color Name | Mapped To (Jetpack Compose) |
120+
| -------------------- | -------------------------------------------- |
121+
| `black` | `Color.Black` |
122+
| `red` | `Color.Red` |
123+
| `green` | `Color.Green` |
124+
| `yellow` | `Color.Yellow` |
125+
| `blue` | `Color.Blue` |
126+
| `magenta` | `Color.Magenta` |
127+
| `cyan` | `Color.Cyan` |
128+
| `white` | `Color.White` |
129+
| `gray`, `grey` | `Color.Gray` |
130+
| `lightgray` | `Color.LightGray` |
131+
| `primary` | `MaterialTheme.colorScheme.primary` |
132+
| `secondary` | `MaterialTheme.colorScheme.secondary` |
133+
| `tertiary` | `MaterialTheme.colorScheme.tertiary` |
134+
| `background` | `MaterialTheme.colorScheme.background` |
135+
| `surface` | `MaterialTheme.colorScheme.surface` |
136+
| `error` | `MaterialTheme.colorScheme.error` |
137+
| `outline` | `MaterialTheme.colorScheme.outline` |
138+
| `inverse_surface` | `MaterialTheme.colorScheme.inverseSurface` |
139+
| `inverse_on_surface` | `MaterialTheme.colorScheme.inverseOnSurface` |
140+
| `inverse_primary` | `MaterialTheme.colorScheme.inversePrimary` |
141+
| `surface_variant` | `MaterialTheme.colorScheme.surfaceVariant` |
142+
| `on_surface_variant` | `MaterialTheme.colorScheme.onSurfaceVariant` |
143+
| `surface_tint` | `MaterialTheme.colorScheme.surfaceTint` |
144+
| `on_surface` | `MaterialTheme.colorScheme.onSurface` |
145+
| `on_primary` | `MaterialTheme.colorScheme.onPrimary` |
146+
| `on_secondary` | `MaterialTheme.colorScheme.onSecondary` |
147+
| `on_tertiary` | `MaterialTheme.colorScheme.onTertiary` |
148+
| `on_background` | `MaterialTheme.colorScheme.onBackground` |
149+
| `on_error` | `MaterialTheme.colorScheme.onError` |
150+
| _(any other value)_ | `Color.Unspecified` |
151+
152+
**Note:** Color names are case-insensitive (e.g., `Red`, `red`, `RED` are all treated the same).
153+
154+
## Tag Nesting and Behavior
155+
156+
In the Jetpack Compose implementation (`toStyleMarkup`):
157+
158+
- Styles are applied segment by segment. When a tag is encountered, the style it defines (e.g., `currentColor`, `isBold`) is set and applied to subsequent text until another relevant tag changes it or the string ends.
159+
- There isn't explicit "closing" tag logic like `[/bold]`. Instead, a new tag like `[color=green]` would change the current color from whatever it was previously. For boolean styles like `bold`, `italic`, `underline`, the provided Kotlin code currently only sets them to `true`. To turn them _off_, you would need to modify the parsing logic to handle specific "off" tags (e.g., `[bold=false]`) or a general reset tag if that functionality is desired. The current parser only activates these styles.
160+
161+
For the shell script, the `sed` command simply removes any recognized tag pattern. It does not interpret nesting or apply styles. The same applies to how an application might parse the `config.json`'s `description` field – it would depend on its specific parsing implementation, but would likely follow the Jetpack Compose behavior if aiming for consistency.

meta/sponsors.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@
55
"url": "https://github.com/denson9874",
66
"amount": 2000
77
},
8+
{
9+
"login": "ApolloGods",
10+
"avatarUrl": "https://avatars.githubusercontent.com/u/16455549?u=e2de99a41ea375c22148f6fe071d9b06cf169896&v=4",
11+
"url": "https://github.com/ApolloGods",
12+
"amount": 500
13+
},
814
{
915
"login": "roeldebruijn1978",
1016
"avatarUrl": "https://avatars.githubusercontent.com/u/36719258?v=4",
1117
"url": "https://github.com/roeldebruijn1978",
1218
"amount": 300
1319
},
20+
{
21+
"login": "lare354",
22+
"avatarUrl": "https://avatars.githubusercontent.com/u/47903733?u=fc7262afddf6a7c201aec9faa27435a5d82d88e4&v=4",
23+
"url": "https://github.com/lare354",
24+
"amount": 500
25+
},
1426
{
1527
"login": "Duan-rax",
1628
"avatarUrl": "https://avatars.githubusercontent.com/u/67225030?v=4",

0 commit comments

Comments
 (0)