diff --git a/README.md b/README.md index 4d061d6..f2d379b 100644 --- a/README.md +++ b/README.md @@ -307,6 +307,7 @@ match logger.file_runtime_state() { - `TextFormatter` / `TextFormatterConfig` 提供 `color_mode = Never | Auto | Always`, 可控制 ANSI 文本着色 - `TextFormatter` / `TextFormatterConfig` 提供 `style_markup = disabled | builtin | full`, 可决定是否解析 style markup 以及是否启用 custom style tag - `message` 支持轻量 inline style tag: `...`, `...`, `<#ff0000>...`, `...` +- 内置语义标签包括: ``, ``, ``, ``, ``, `` - 运行期样式标签 API: `TextStyle`, `StyleTagRegistry`, `style_tag_registry()`, `default_style_tag_registry()`, `set_tag(...)`, `define_alias(...)` - 样式标签优先级: formatter 局部 `style_tags` > 全局 style tag registry > 内置标签 - `sink.text_formatter.style_tags` 现支持最小对象映射配置, 可声明 `fg`, `bg`, `bold`, `dim`, `italic`, `underline` diff --git a/bitlogger/BitLogger_test.mbt b/bitlogger/BitLogger_test.mbt index 848cbf3..0345be2 100644 --- a/bitlogger/BitLogger_test.mbt +++ b/bitlogger/BitLogger_test.mbt @@ -253,14 +253,14 @@ test "config builtin style markup ignores custom tags" { color_mode=ColorMode::Always, style_markup=StyleMarkupMode::Builtin, style_tags={ - "accent": text_style(fg=Some("#4cc9f0"), bold=true), + "brand": text_style(fg=Some("#4cc9f0"), bold=true), }, ) let rendered = format_text( - Record::new(Level::Info, "custom builtin"), + Record::new(Level::Info, "custom builtin"), formatter=formatter.to_formatter(), ) - inspect(rendered, content="custom \u{001b}[31mbuiltin\u{001b}[0m") + inspect(rendered, content="custom \u{001b}[31mbuiltin\u{001b}[0m") } test "config disabled style markup keeps raw tags" { diff --git a/bitlogger/BitLogger_wbtest.mbt b/bitlogger/BitLogger_wbtest.mbt index 3df1c00..6dc95a9 100644 --- a/bitlogger/BitLogger_wbtest.mbt +++ b/bitlogger/BitLogger_wbtest.mbt @@ -141,12 +141,12 @@ test "text formatter builtin style markup mode ignores custom tags" { color_mode=ColorMode::Always, style_markup=StyleMarkupMode::Builtin, ).with_style_tags( - style_tag_registry().set_tag("accent", fg=Some("#4cc9f0"), bold=true), + style_tag_registry().set_tag("brand", fg=Some("#4cc9f0"), bold=true), ) - let rec = record(Level::Info, "custom builtin") + let rec = record(Level::Info, "custom builtin") inspect( format_text(rec, formatter=formatter), - content="custom \u{001b}[31mbuiltin\u{001b}[0m", + content="custom \u{001b}[31mbuiltin\u{001b}[0m", ) } @@ -230,6 +230,35 @@ test "style tag alias can reuse builtin tags" { ) } +test "builtin semantic style tags are available" { + let formatter = text_formatter( + show_level=false, + show_target=false, + color_mode=ColorMode::Always, + style_markup=StyleMarkupMode::Builtin, + ) + let rec = record(Level::Info, "ok careful boom quiet") + inspect( + format_text(rec, formatter=formatter), + content="\u{001b}[32;1mok\u{001b}[0m \u{001b}[33;1mcareful\u{001b}[0m \u{001b}[31;1mboom\u{001b}[0m \u{001b}[90;2mquiet\u{001b}[0m", + ) +} + +test "builtin semantic style tags can still be overridden" { + let formatter = text_formatter( + show_level=false, + show_target=false, + color_mode=ColorMode::Always, + ).with_style_tags( + default_style_tag_registry().set_tag("success", fg=Some("#00ffaa"), underline=true), + ) + let rec = record(Level::Info, "ok") + inspect( + format_text(rec, formatter=formatter), + content="\u{001b}[38;2;0;255;170;4mok\u{001b}[0m", + ) +} + test "text formatter template respects disabled fields" { let rec = record(Level::Warn, "just message", target="svc") let formatter = text_formatter( diff --git a/bitlogger/README.mbt.md b/bitlogger/README.mbt.md index fafb3cb..f1ac361 100644 --- a/bitlogger/README.mbt.md +++ b/bitlogger/README.mbt.md @@ -253,6 +253,7 @@ test { - `color_mode` / `color_mode`: `never`, `auto`, `always` - `style_markup` / `style_markup`: `disabled`, `builtin`, `full` - inline style tags / inline 样式标签: `...`, `...`, `<#ff0000>...`, `...` +- builtin semantic tags / 内置语义标签: ``, ``, ``, ``, ``, `` - runtime style tags / 运行期样式标签: `TextStyle`, `StyleTagRegistry`, `style_tag_registry()`, `default_style_tag_registry()`, `set_tag(...)`, `define_alias(...)` - style tag priority / 标签优先级: formatter local `style_tags` > global style tag registry > builtin tags - `sink.text_formatter.style_tags` / `sink.text_formatter.style_tags` 现支持最小对象映射: `fg`, `bg`, `bold`, `dim`, `italic`, `underline` diff --git a/bitlogger/formatter.mbt b/bitlogger/formatter.mbt index 034b04a..11079b4 100644 --- a/bitlogger/formatter.mbt +++ b/bitlogger/formatter.mbt @@ -120,6 +120,12 @@ pub fn default_style_tag_registry() -> StyleTagRegistry { .set_tag("bright_magenta", fg=Some("bright_magenta")) .set_tag("bright_cyan", fg=Some("bright_cyan")) .set_tag("bright_white", fg=Some("bright_white")) + .set_tag("accent", fg=Some("bright_cyan"), bold=true) + .set_tag("info", fg=Some("cyan")) + .set_tag("success", fg=Some("green"), bold=true) + .set_tag("warning", fg=Some("yellow"), bold=true) + .set_tag("danger", fg=Some("red"), bold=true) + .set_tag("muted", fg=Some("bright_black"), dim=true) .set_tag("b", bold=true) .set_tag("dim", dim=true) .set_tag("i", italic=true) @@ -442,6 +448,12 @@ fn builtin_text_style_for_tag(tag : String) -> TextStyle? { "bright_magenta" => Some(text_style(fg=Some("bright_magenta"))) "bright_cyan" => Some(text_style(fg=Some("bright_cyan"))) "bright_white" => Some(text_style(fg=Some("bright_white"))) + "accent" => Some(text_style(fg=Some("bright_cyan"), bold=true)) + "info" => Some(text_style(fg=Some("cyan"))) + "success" => Some(text_style(fg=Some("green"), bold=true)) + "warning" => Some(text_style(fg=Some("yellow"), bold=true)) + "danger" => Some(text_style(fg=Some("red"), bold=true)) + "muted" => Some(text_style(fg=Some("bright_black"), dim=true)) "b" => Some(text_style(bold=true)) "dim" => Some(text_style(dim=true)) "i" => Some(text_style(italic=true)) diff --git a/docs/README-en.md b/docs/README-en.md index 52d0f2a..43d675a 100644 --- a/docs/README-en.md +++ b/docs/README-en.md @@ -283,6 +283,7 @@ match logger.file_runtime_state() { - `TextFormatter` and `TextFormatterConfig` now include `color_mode = Never | Auto | Always` for ANSI text coloring control. - `TextFormatter` and `TextFormatterConfig` also include `style_markup = disabled | builtin | full` so callers can choose whether style markup is parsed and whether custom tags are active. - `message` also supports lightweight inline style tags such as `...`, `...`, `<#ff0000>...`, and `...`. +- Builtin semantic tags now include ``, ``, ``, ``, ``, and ``. - Runtime style-tag APIs now include `TextStyle`, `StyleTagRegistry`, `style_tag_registry()`, `default_style_tag_registry()`, `set_tag(...)`, and `define_alias(...)`. - Style-tag lookup priority is formatter-local `style_tags` > global style tag registry > builtin tags. - `sink.text_formatter.style_tags` now supports a minimal object mapping with `fg`, `bg`, `bold`, `dim`, `italic`, and `underline`. diff --git a/docs/changes/0.4.0.md b/docs/changes/0.4.0.md index a41384d..aced517 100644 --- a/docs/changes/0.4.0.md +++ b/docs/changes/0.4.0.md @@ -16,6 +16,7 @@ version 0.4.0 - feat: support minimal `sink.text_formatter.style_tags` JSON config parsing and serialization for custom formatter tag styles - feat: add `StyleMarkupMode = Disabled | Builtin | Full` plus formatter helpers so callers can explicitly disable style parsing or allow builtin-only parsing - feat: support `sink.text_formatter.style_markup` in JSON config parsing and serialization +- feat: add builtin semantic style tags such as `accent`, `info`, `success`, `warning`, `danger`, and `muted` ### Test @@ -27,6 +28,7 @@ version 0.4.0 - test: cover custom tags, builtin-tag override, formatter-vs-global priority, global registry fallback, and alias reuse - test: cover formatter `style_tags` JSON parsing, config roundtrip, JSON helper export, and config-driven styled formatter rendering - test: cover disabled markup mode, builtin-only mode, and config-driven `style_markup` behavior +- test: cover builtin semantic tag rendering and confirm user overrides still take precedence ### Example