Skip to content

Releases: razkar-studio/farben

v0.13.0 - I'm Lost!

04 Apr 11:04

Choose a tag to compare

Changelog

Farben is constantly updating. All notable changes to Farben will be documented here.

[0.9.0] - 2026-04-04 - farben-core

Added

  • Lossy degrading. When the terminal does not support 24-bit true color, RGB values are
    automatically degraded to the nearest ANSI256 color. When the terminal only supports
    basic ANSI colors (8/16 colors), RGB and ANSI256 values are degraded to the nearest
    named color. The degrader module uses the COLORTERM and TERM environment variables
    to detect terminal color capabilities at runtime. Opt-out-able via lossy default feature.
  • Zero external dependencies added to core library internals.

[0.13.0] - 2026-04-04 - farben

Changed

  • farben-core dependency bumped to 0.9.0, picking up lossy degrading support.
  • opt-out-able lossy default feature, piping to farben-core's own lossy feature.

v0.12.0 - Write With Color

04 Apr 10:19

Choose a tag to compare

Changelog

Farben is constantly updating. Notable changes are documented here.

[0.12.0] - 2026-04-04 - farben

Added

  • cwrite!, cwriteln!, cwriteb!, cwritebln! - writer variants of the colored print macros.
    Work with any Write implementor. Useful for writing to files, String buffers, or custom writers.
    All four support the same markup features as the stdout variants (named colors, RGB, ANSI256, emphasis,
    bleeding via the b variants).

v0.11.0: Nice Errors Man

04 Apr 08:08

Choose a tag to compare

...shut up. Regardless,

Changelog

All notable changes to Farben will be documented here.

[0.8.0] - 2026-04-04 - farben-core

Added

  • RegistryError enum — a separate error type for registry operations (set_prefix, insert_style).
    Split out from LexError because registry errors have no source position (they occur outside markup
    parsing). Has one variant: UnknownStyle(String).
  • LexErrorDisplay<'a> struct — wraps a &LexError and the original &str input to produce
    compiler-style diagnostic output. Renders two lines: the full input string, then a caret (^)
    aligned to the byte offset of the error. Example:
       | [bold unknown]text
       |       ^^^^^^^ invalid tag: 'unknown'
    

Changed

  • All LexError variants now carry a position: usize field (byte offset into the markup string).
    Affected variants: UnclosedTag, InvalidTag, UnclosedValue, InvalidArgumentCount,
    InvalidValue, InvalidResetTarget. Previously no variants stored position info.
  • LexError::UnknownStyle removed — registry errors now use RegistryError::UnknownStyle instead.
  • LexError's Display impl now includes position in every message
    (e.g. "invalid tag 'foo' at position 5").

[0.11.0] - 2026-04-04 - farben

Added

  • farben::prelude module - the recommended import path going forward. use farben::prelude::*
    brings every user-facing item into scope (functions, macros, types) gated by the same feature
    flags as their definitions. Prefer this over use farben::*, which also pulls in
    color_runtime and validate_color - items that are pub only to satisfy macro expansion,
    not intended for direct use.

Changed

  • farben-core dependency bumped to 0.8.0, picking up position-aware LexError variants and
    the new LexErrorDisplay diagnostic formatter. try_color error messages now include the byte
    offset of the offending token.
  • All documentation and examples updated to use use farben::prelude::*.

v0.10.0 - ANStripsI and Respects

04 Apr 08:06

Choose a tag to compare

Changelog

Farben is constantly shipping. Notable changes will be documented here.

[2026-04-04]

Added

  • ansi_strip!(...) — macro that accepts format!-style arguments, builds the string,
    then strips all CSI ANSI escape sequences from the result. Non-CSI ESC bytes pass
    through unchanged. Returns String.
  • strip_ansi re-exported at the farben crate root from farben-core::strip::strip_ansi,
    making it available via use farben::* and as the expansion target for ansi_strip!.

Changed

  • farben-core dependency bumped to 0.7.0.

[0.7.0] - 2026-04-04 - farben-core

Added

  • env module: runtime detection of whether ANSI color output should be enabled.
    Respects the NO_COLOR and FORCE_COLOR environment variable conventions (in that
    order), then falls back to TTY detection. Result is computed once per process and
    cached via OnceLock.
    • color_enabled(): returns the cached bool for the current process.
    • TTY detection on Unix via isatty(1); on Windows via GetStdHandle +
      GetConsoleMode; false on all other targets.
  • strip module: utilities for removing ANSI escape sequences from strings.
    • strip_ansi(input): strips CSI sequences (ESC [ ... <letter>) from a string
      and returns plain text. Non-CSI ESC bytes are passed through unchanged.
      Useful for measuring display width, plain-text logging, or piping to tools that
      do not interpret ANSI codes.

v0.9.0

20 Mar 10:08

Choose a tag to compare

v0.9.0: Errors, and nothing else.

All notable changes to Farben will be documented here.

[0.9.0] - 2026-03-20 - farben

Added

  • ceprint!, ceprintln!, ceprintb!, ceprintbln! — stderr variants of the colored print macros.
  • mdeprint!, mdeprintln! — stderr variants of the inline markdown print macros.
  • Empty invocation support for all print macros. cprintln!() now prints a bare newline,
    cprint!() prints nothing — consistent with how println!() and print!() behave in std.
    Applies to ceprint!, ceprintln!, mdprint!, mdprintln!, mdeprint!, mdeprintln!,
    and all bleed variants.

Changed

  • src/lib.rs split into focused modules: functions.rs, macros/color.rs,
    macros/format.rs, macros/markdown.rs, macros/eprint.rs, and tests.rs.
    No public API changes.

Mark That Down

17 Mar 05:02

Choose a tag to compare

[0.8.0] - 2026-03-17 - farben

Added

  • markdown() — runtime function that parses and renders inline markdown into
    an ANSI-escaped string. Always succeeds. Enabled via the markdown feature.
  • md_fmt!() — renders inline markdown with format arguments. Always runtime.
    Enabled via the markdown feature.
  • mdprint!() — prints inline markdown to stdout without a newline. Runtime
    under markdown, compile-time under markdown-compile.
  • mdprintln!() — prints inline markdown to stdout with a trailing newline.
    Runtime under markdown, compile-time under markdown-compile.

Changed

  • style!() and prefix!() macros moved from farben-core to farben,
    under the format feature flag.

Added (features)

  • markdown feature — enables runtime markdown rendering via farben-md.
  • markdown-compile feature — enables both markdown and compile, with
    compile-time markdown rendering via farben-macros.

[0.8.0 / 0.4.0 / 0.1.0] - 2026-03-17 - Global

Markdown update. Introduces farben-md as a new workspace crate and wires
inline markdown rendering into the full Farben pipeline.

Added

  • farben-md — new crate providing inline markdown tokenization and rendering.
    Depends on farben-core for ANSI encoding.
  • color_to_ansi() and emphasis_to_ansi() made public in farben-core
    0.6.2, enabling farben-md to delegate ANSI encoding without reimplementing it.

Dusting

16 Mar 04:10

Choose a tag to compare

Changelog

All notable changes to Farben will be documented here.


[0.3.0] - 2026-03-16

Changed

  • colorb! — replaced one-line stub doc ("Same as color!, but bleeds.") with a full
    doc comment explaining what bleed means, when to use it, and how it differs from
    color!. Includes a working example.
  • validate_color! — removed misleading user-facing example. The macro is internal
    infrastructure used by color_fmt!, cprint!, and cprintln!; the example implied
    direct use was intended. Doc comment now explicitly marks it as internal and directs
    users toward color! and color_fmt! instead.

[0.7.0] - 2026-03-16 - farben

Added

  • colorb — added missing doc comment explaining bleed behavior and when to use it
    over color.
  • color_fmt! (compile-time variant) — added missing doc comment. Previously the
    runtime variant was documented but the compile-feature counterpart had none.

Changed

  • Crate-level doc comment revised: fixed grammar ("uses a markup-language-like syntax
    to your string" → "applies a markup-like syntax to your strings") and capitalized
    "German".

Fixed

  • cprint! (compile-time variant) — example referenced unbound variable message.
    Added let message = "I don't know"; to the example so it compiles as a doctest.
  • cprintln! (compile-time variant) — example referenced unbound variable result.
    Added let result = "We did it!"; to the example so it compiles as a doctest.
  • test_try_color_inline_reset — strengthened assertion from
    s.contains("\x1b[0m") (always true due to trailing reset) to a full equality check
    against the expected output "\x1b[31mbefore\x1b[0mafter\x1b[0m".

[0.6.0] - 2026-03-16 - farben-core

Added

  • LexError::InvalidResetTarget — new error variant returned when a reset tag targets
    something that cannot be reset (e.g. [//] or [/prefix]). Previously caused a panic.
  • LexError::UnknownStyle — new error variant returned by registry::set_prefix when
    the given style name has not been registered.
  • registry::set_prefix now returns Result<(), LexError> instead of (), allowing
    callers to handle unknown style names without panicking.

Changed

  • ansi::style_to_ansi promoted from pub(crate) to pub. Users building on top of
    farben-core can now call it directly to convert a Style into a combined SGR sequence.
  • ansi::style_to_ansi — removed #[allow(unused)] attribute now that the function is
    part of the public API.
  • registry::prefix! macro updated to call .expect() on the Result returned by
    set_prefix, preserving the existing panic-on-misuse behavior at the macro callsite
    while keeping the underlying function non-panicking.
  • LexError::InvalidArgumentCount display message improved from
    "expected N, got M" to "expected N arguments, got M" for clarity.

Fixed

  • lexer::parse_part — replaced panic! with Err(LexError::InvalidResetTarget) when
    a reset tag targets a Reset or Prefix node. User-supplied markup can no longer crash
    the process through the try_color path.
  • registry::set_prefix — replaced panic! with Err(LexError::UnknownStyle) when the
    style name is not found in the registry.
  • errors.rs — corrected typo in UnclosedValue display message:
    "parantheses" → "parentheses".
  • ansi::NamedColor doc comment — corrected "eight standard ANSI named colors" to
    "sixteen ANSI named colors" (eight standard + eight bright variants).
  • ansi::style_to_ansi — added a working doctest demonstrating bold + named color output.
  • parser::render — removed unnecessary .as_str() calls on String return values from
    color_to_ansi and emphasis_to_ansi; push_str accepts &str via Deref directly.

v0.6.0

16 Mar 00:24

Choose a tag to compare

0.6.0: Death To Inclusivity (IN RESETTING)

All notable changes to Farben will be documented here.


[0.6.0] - 2026-03-16

Global Farben Update

Added

  • Specified resets — [/bold], [/red], [/italic] etc. reset only the named style, leaving all other active styles intact
  • TagType::Reset now takes Option<Box<TagType>>None for full reset [/], Some(tag) for partial reset
  • parser::render now maintains an active tag stack, re-emitting surviving styles after a partial reset
  • Panics if a partial reset targets TagType::Reset or TagType::Prefix — both are invalid reset targets

Changed

  • TagType::Reset changed from a unit variant to Reset(Option<Box<TagType>>)
  • All existing [/] full reset behavior is preserved via Reset(None)

Fixed

  • Fixed a bug where colorb!() did not exist when using the compile feature

[0.2.6] - 2026-03-16 - farben/farben-macros

Added

  • Minor dependency update to farben-core

v0.5.0

15 Mar 05:11

Choose a tag to compare

🎉 0.5.0: Halfway There!

All notable changes to Farben will be documented here.


[0.5.0] - 2026-03-15

Global Farben update due to changes to farben-core.

Added

  • Added bugs
  • Style::prefix field, optional text prepended before the style's ANSI codes when the style is applied
  • TagType::Prefix(String) variant, carries prefix text through the token pipeline to the renderer
  • set_prefix(), sets the prefix on an existing registry entry, panics if the style is not found
  • prefix!() macro, user-facing API for binding a text prefix to a named style
  • style_to_tags() now emits TagType::Prefix as the first tag when a prefix is present
  • parser::render() now handles TagType::Prefix by appending the text directly to output
  • format default feature, gates logic for style!() and prefix!()

Changed

  • style_to_tags() no longer returns early on reset when a prefix is present, prefix is always emitted first
  • style!() is now gated to the format feature

[0.4.1] - 2026-03-15 - farben-core

Fixed

  • Bug where prefix!() interferes with actual color styling

[0.2.4] - 2026-03-15 - farben-macros

Added

  • Minor dependency update to farben-core

[0.2.3] - 2026-03-15 - farben-macros

Added

  • Minor dependency update to farben-core

v0.4.0

15 Mar 00:17

Choose a tag to compare

Changelog

All notable changes to Farben will be documented here.


[0.4.0] - 2026-03-15

Public Farben Update. Changes to farben-core, farben, and farben-macros is displayed here.

Added

  • Style::parse() — builds a Style from farben markup string
  • Style::reset field — when true, overrides all other style attributes with a full SGR reset
  • registry module — global style registry backed by OnceLock<Mutex<HashMap<String, Style>>>
  • insert_style() — inserts a named style into the global registry
  • search_registry() — looks up a named style from the global registry
  • style!() macro — user-facing API for defining custom named styles
  • style_to_tags() — converts a Style into a Vec<TagType> for lexer expansion
  • Custom tag resolution in parse_part() — unknown tags now check the registry before returning InvalidTag
  • parse_part() return type changed from Result<TagType, LexError> to Result<Vec<TagType>, LexError> to support style expansion
  • colorb!() bleeds at compile-time with the colorb() runtime counterpart

Changed

  • parse_tag() updated to flatten nested Vec<TagType> results from parse_part()
  • All functions, when using compile can now benefit from compile-time processing instead of just validation

Fixed

  • color!() now auto-resets.