diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f587e1..57fe2e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ * network: `ssid`, `signal`, `rx-bitrate` and `rx-bitrate` tags. * network: `poll-interval` option (for the new `signal` and `*-bitrate` tags). +* tags: percentage formatter, for range tags: `{tag_name:%}`. ### Changed diff --git a/doc/yambar-tags.5.scd b/doc/yambar-tags.5.scd index 1e3c138..8d357cb 100644 --- a/doc/yambar-tags.5.scd +++ b/doc/yambar-tags.5.scd @@ -38,9 +38,50 @@ The available tag *types* are: # FORMATTING -As mentioned above, each tag type has a default representation that is -used when the tag is rendered by a string particle. +A tag may be followed by one or more formatters that alter the tags +rendition. + +Formatters are added by appending a ':' separated list of formatter +names: + + "{tag_name:max:hex}" + +In the table below, "kind" describes the type of action performed by +the formatter: + +- *format*: changes the representation of the tag's value +- *selector*: changes what to render + +In general, formatters of the same kind cannot be combined; if +multiple formatters of the same kind are specified, the last one will +be used. + +[[ *Formatter* +:[ *Kind* +:[ *Description* +:[ *Applies to*] +| hex +: format +: Renders a tag's value in hex +: All tag types +| oct +: format +: Renders a tag's value in octal +: All tag types +| % +: format +: Renders a range tag's value as a percentage value +: Range tags +| min +: selector +: Renders a range tag's mininum value +: Range tags +| max +: selector +: Renders a range tag's maximum value +: Range tags +| unit +: selector +: Renders a realtime tag's unit (e.g. "s", or "ms") +: Realtime tags -All integer, floating point and boolean tag types can be modified to -instead be rendered in hexadecimal or octal form, by appending either -the *:hex* or *:oct* suffixes. For example, _\"{tag_name:hex}\"_. \ No newline at end of file diff --git a/tag.c b/tag.c index 8ca7e52..0548b2e 100644 --- a/tag.c +++ b/tag.c @@ -459,7 +459,7 @@ tags_expand_template(const char *template, const struct tag_set *tags) sbuf_append_at_most(&formatted, template, begin - template); /* Parse arguments */ - enum { FMT_DEFAULT, FMT_HEX, FMT_OCT } format = FMT_DEFAULT; + enum { FMT_DEFAULT, FMT_HEX, FMT_OCT, FMT_PERCENT } format = FMT_DEFAULT; enum { VALUE_VALUE, VALUE_MIN, VALUE_MAX, VALUE_UNIT } kind = VALUE_VALUE; for (size_t i = 0; i < MAX_TAG_ARGS; i++) { @@ -469,12 +469,16 @@ tags_expand_template(const char *template, const struct tag_set *tags) format = FMT_HEX; else if (strcmp(tag_args[i], "oct") == 0) format = FMT_OCT; + else if (strcmp(tag_args[i], "%") == 0) + format = FMT_PERCENT; else if (strcmp(tag_args[i], "min") == 0) kind = VALUE_MIN; else if (strcmp(tag_args[i], "max") == 0) kind = VALUE_MAX; else if (strcmp(tag_args[i], "unit") == 0) kind = VALUE_UNIT; + else + LOG_WARN("invalid tag formatter: %s", tag_args[i]); } /* Copy tag value */ @@ -493,20 +497,40 @@ tags_expand_template(const char *template, const struct tag_set *tags) sbuf_append(&formatted, str); break; } + + case FMT_PERCENT: { + const long min = tag->min(tag); + const long max = tag->max(tag); + const long cur = tag->as_int(tag); + + char str[4]; + snprintf(str, sizeof(str), "%lu", (cur - min) * 100 / (max - min)); + sbuf_append(&formatted, str); + break; + } } break; case VALUE_MIN: case VALUE_MAX: { - const long value = kind == VALUE_MIN ? tag->min(tag) : tag->max(tag); + const long min = tag->min(tag); + const long max = tag->max(tag); + long value = kind == VALUE_MIN ? min : max; const char *fmt; switch (format) { case FMT_DEFAULT: fmt = "%ld"; break; case FMT_HEX: fmt = "%lx"; break; case FMT_OCT: fmt = "%lo"; break; + + case FMT_PERCENT: + value = (value - min) * 100 / (max - min); + fmt = "%lu"; + break; } + + char str[24]; snprintf(str, sizeof(str), fmt, value); sbuf_append(&formatted, str);