Added support for Pango markup.
This commit is contained in:
parent
876c1cef8d
commit
dcd0518e25
14
i3status.c
14
i3status.c
@ -295,6 +295,7 @@ int main(int argc, char *argv[]) {
|
|||||||
CFG_STR("color_separator", "#333333", CFGF_NONE),
|
CFG_STR("color_separator", "#333333", CFGF_NONE),
|
||||||
CFG_INT("interval", 1, CFGF_NONE),
|
CFG_INT("interval", 1, CFGF_NONE),
|
||||||
CFG_COLOR_OPTS("#00FF00", "#FFFF00", "#FF0000"),
|
CFG_COLOR_OPTS("#00FF00", "#FFFF00", "#FF0000"),
|
||||||
|
CFG_STR("markup", "none", CFGF_NONE),
|
||||||
CFG_END()};
|
CFG_END()};
|
||||||
|
|
||||||
cfg_opt_t run_watch_opts[] = {
|
cfg_opt_t run_watch_opts[] = {
|
||||||
@ -365,6 +366,7 @@ int main(int argc, char *argv[]) {
|
|||||||
cfg_opt_t tztime_opts[] = {
|
cfg_opt_t tztime_opts[] = {
|
||||||
CFG_STR("format", "%Y-%m-%d %H:%M:%S %Z", CFGF_NONE),
|
CFG_STR("format", "%Y-%m-%d %H:%M:%S %Z", CFGF_NONE),
|
||||||
CFG_STR("timezone", "", CFGF_NONE),
|
CFG_STR("timezone", "", CFGF_NONE),
|
||||||
|
CFG_STR("format_time", NULL, CFGF_NONE),
|
||||||
CFG_CUSTOM_ALIGN_OPT,
|
CFG_CUSTOM_ALIGN_OPT,
|
||||||
CFG_CUSTOM_MIN_WIDTH_OPT,
|
CFG_CUSTOM_MIN_WIDTH_OPT,
|
||||||
CFG_END()};
|
CFG_END()};
|
||||||
@ -532,6 +534,14 @@ int main(int argc, char *argv[]) {
|
|||||||
if (!valid_color(cfg_getstr(cfg_general, "color_good")) || !valid_color(cfg_getstr(cfg_general, "color_degraded")) || !valid_color(cfg_getstr(cfg_general, "color_bad")) || !valid_color(cfg_getstr(cfg_general, "color_separator")))
|
if (!valid_color(cfg_getstr(cfg_general, "color_good")) || !valid_color(cfg_getstr(cfg_general, "color_degraded")) || !valid_color(cfg_getstr(cfg_general, "color_bad")) || !valid_color(cfg_getstr(cfg_general, "color_separator")))
|
||||||
die("Bad color format");
|
die("Bad color format");
|
||||||
|
|
||||||
|
char *markup_str = cfg_getstr(cfg_general, "markup");
|
||||||
|
if (strcasecmp(markup_str, "pango") == 0)
|
||||||
|
markup_format = M_PANGO;
|
||||||
|
else if (strcasecmp(markup_str, "none") == 0)
|
||||||
|
markup_format = M_NONE;
|
||||||
|
else
|
||||||
|
die("Unknown markup format: \"%s\"\n", markup_str);
|
||||||
|
|
||||||
#if YAJL_MAJOR >= 2
|
#if YAJL_MAJOR >= 2
|
||||||
yajl_gen json_gen = yajl_gen_alloc(NULL);
|
yajl_gen json_gen = yajl_gen_alloc(NULL);
|
||||||
#else
|
#else
|
||||||
@ -648,13 +658,13 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
CASE_SEC("time") {
|
CASE_SEC("time") {
|
||||||
SEC_OPEN_MAP("time");
|
SEC_OPEN_MAP("time");
|
||||||
print_time(json_gen, buffer, NULL, cfg_getstr(sec, "format"), NULL, tv.tv_sec);
|
print_time(json_gen, buffer, NULL, cfg_getstr(sec, "format"), NULL, NULL, tv.tv_sec);
|
||||||
SEC_CLOSE_MAP;
|
SEC_CLOSE_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE_SEC_TITLE("tztime") {
|
CASE_SEC_TITLE("tztime") {
|
||||||
SEC_OPEN_MAP("tztime");
|
SEC_OPEN_MAP("tztime");
|
||||||
print_time(json_gen, buffer, title, cfg_getstr(sec, "format"), cfg_getstr(sec, "timezone"), tv.tv_sec);
|
print_time(json_gen, buffer, title, cfg_getstr(sec, "format"), cfg_getstr(sec, "timezone"), cfg_getstr(sec, "format_time"), tv.tv_sec);
|
||||||
SEC_CLOSE_MAP;
|
SEC_CLOSE_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,9 @@ enum { O_DZEN2,
|
|||||||
O_TERM,
|
O_TERM,
|
||||||
O_NONE } output_format;
|
O_NONE } output_format;
|
||||||
|
|
||||||
|
enum { M_PANGO,
|
||||||
|
M_NONE } markup_format;
|
||||||
|
|
||||||
char *pct_mark;
|
char *pct_mark;
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -78,6 +81,9 @@ char *pct_mark;
|
|||||||
* not forgotten in the module */ \
|
* not forgotten in the module */ \
|
||||||
*outwalk = '\0'; \
|
*outwalk = '\0'; \
|
||||||
if (output_format == O_I3BAR) { \
|
if (output_format == O_I3BAR) { \
|
||||||
|
char *_markup = cfg_getstr(cfg_general, "markup"); \
|
||||||
|
yajl_gen_string(json_gen, (const unsigned char *) "markup", strlen("markup")); \
|
||||||
|
yajl_gen_string(json_gen, (const unsigned char *)_markup, strlen(_markup)); \
|
||||||
yajl_gen_string(json_gen, (const unsigned char *) "full_text", strlen("full_text")); \
|
yajl_gen_string(json_gen, (const unsigned char *) "full_text", strlen("full_text")); \
|
||||||
yajl_gen_string(json_gen, (const unsigned char *)text, strlen(text)); \
|
yajl_gen_string(json_gen, (const unsigned char *)text, strlen(text)); \
|
||||||
} else { \
|
} else { \
|
||||||
@ -176,6 +182,7 @@ void print_separator(const char *separator);
|
|||||||
char *color(const char *colorstr);
|
char *color(const char *colorstr);
|
||||||
char *endcolor() __attribute__((pure));
|
char *endcolor() __attribute__((pure));
|
||||||
void reset_cursor(void);
|
void reset_cursor(void);
|
||||||
|
void maybe_escape_markup(char *text, char **buffer);
|
||||||
|
|
||||||
/* src/auto_detect_format.c */
|
/* src/auto_detect_format.c */
|
||||||
char *auto_detect_format();
|
char *auto_detect_format();
|
||||||
@ -193,7 +200,7 @@ const char *first_eth_interface(const net_type_t type);
|
|||||||
void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
|
void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
|
||||||
void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold);
|
void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold);
|
||||||
void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds);
|
void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, const char *format_down, const char *status_chr, const char *status_bat, const char *status_full, int low_threshold, char *threshold_type, bool last_full_capacity, bool integer_battery_capacity, bool hide_seconds);
|
||||||
void print_time(yajl_gen json_gen, char *buffer, const char *title, const char *format, const char *tz, time_t t);
|
void print_time(yajl_gen json_gen, char *buffer, const char *title, const char *format, const char *tz, const char *format_time, time_t t);
|
||||||
void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t);
|
void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t);
|
||||||
const char *get_ip_addr(const char *interface);
|
const char *get_ip_addr(const char *interface);
|
||||||
void print_wireless_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down);
|
void print_wireless_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down);
|
||||||
|
@ -184,6 +184,13 @@ format as the separator is drawn by i3bar directly otherwise. For the other
|
|||||||
output formats, the provided non-empty string will be automatically enclosed
|
output formats, the provided non-empty string will be automatically enclosed
|
||||||
with the necessary coloring bits if color support is enabled.
|
with the necessary coloring bits if color support is enabled.
|
||||||
|
|
||||||
|
i3bar supports Pango markup, allowing your format strings to specify font
|
||||||
|
color, size, etc. by setting the +markup+ directive to "pango". Note that the
|
||||||
|
ampersand ("&"), less-than ("<"), greater-than (">"), single-quote ("'"), and
|
||||||
|
double-quote (""") characters need to be replaced with "`&`", "`<`",
|
||||||
|
"`>`", "`'`", and "`"`" respectively. This is done automatically
|
||||||
|
for generated content (e.g. wireless ESSID, time).
|
||||||
|
|
||||||
*Example configuration*:
|
*Example configuration*:
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
general {
|
general {
|
||||||
@ -417,6 +424,18 @@ in the +tztime+ module.
|
|||||||
|
|
||||||
*Example timezone*: +Europe/Berlin+
|
*Example timezone*: +Europe/Berlin+
|
||||||
|
|
||||||
|
If you would like to use markup in this section, there is a separate
|
||||||
|
+format_time+ option that is automatically escaped. Its output then replaces
|
||||||
|
%time in the format string.
|
||||||
|
|
||||||
|
*Example configuration (markup)*:
|
||||||
|
-------------------------------------------------------------
|
||||||
|
tztime time {
|
||||||
|
format = "<span foreground='#ffffff'>time:</span> %time"
|
||||||
|
format_time = "%H:%M %Z"
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------
|
||||||
|
|
||||||
=== DDate
|
=== DDate
|
||||||
|
|
||||||
Outputs the current discordian date in user-specified format. See +ddate(1)+ for
|
Outputs the current discordian date in user-specified format. See +ddate(1)+ for
|
||||||
|
43
src/output.c
43
src/output.c
@ -78,3 +78,46 @@ void print_separator(const char *separator) {
|
|||||||
void reset_cursor(void) {
|
void reset_cursor(void) {
|
||||||
printf("\033[?25h");
|
printf("\033[?25h");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Escapes ampersand, less-than, greater-than, single-quote, and double-quote
|
||||||
|
* characters with the corresponding Pango markup strings if markup is enabled.
|
||||||
|
* See the glib implementation:
|
||||||
|
* https://git.gnome.org/browse/glib/tree/glib/gmarkup.c?id=03db1f455b4265654e237d2ad55464b4113cba8a#n2142
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void maybe_escape_markup(char *text, char **buffer) {
|
||||||
|
if (markup_format == M_NONE) {
|
||||||
|
*buffer += sprintf(*buffer, "%s", text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (; *text != '\0'; text++) {
|
||||||
|
switch (*text) {
|
||||||
|
case '&':
|
||||||
|
*buffer += sprintf(*buffer, "%s", "&");
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
*buffer += sprintf(*buffer, "%s", "<");
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
*buffer += sprintf(*buffer, "%s", ">");
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
*buffer += sprintf(*buffer, "%s", "'");
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
*buffer += sprintf(*buffer, "%s", """);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((0x1 <= *text && *text <= 0x8) ||
|
||||||
|
(0xb <= *text && *text <= 0xc) ||
|
||||||
|
(0xe <= *text && *text <= 0x1f) ||
|
||||||
|
(0x7f <= *text && *text <= 0x84) ||
|
||||||
|
(0x86 <= *text && *text <= 0x9f))
|
||||||
|
*buffer += sprintf(*buffer, "&#x%x;", *text);
|
||||||
|
else
|
||||||
|
*(*buffer)++ = *text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,17 +33,36 @@ void set_timezone(const char *tz) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_time(yajl_gen json_gen, char *buffer, const char *title, const char *format, const char *tz, time_t t) {
|
void print_time(yajl_gen json_gen, char *buffer, const char *title, const char *format, const char *tz, const char *format_time, time_t t) {
|
||||||
|
const char *walk;
|
||||||
char *outwalk = buffer;
|
char *outwalk = buffer;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
char timebuf[1024];
|
||||||
|
|
||||||
if (title != NULL)
|
if (title != NULL)
|
||||||
INSTANCE(title);
|
INSTANCE(title);
|
||||||
|
|
||||||
/* Convert time and format output. */
|
|
||||||
set_timezone(tz);
|
set_timezone(tz);
|
||||||
localtime_r(&t, &tm);
|
localtime_r(&t, &tm);
|
||||||
outwalk += strftime(outwalk, 4095, format, &tm);
|
|
||||||
|
if (format_time == NULL) {
|
||||||
|
strftime(timebuf, sizeof(timebuf), format, &tm);
|
||||||
|
maybe_escape_markup(timebuf, &outwalk);
|
||||||
|
} else {
|
||||||
|
for (walk = format; *walk != '\0'; walk++) {
|
||||||
|
if (*walk != '%') {
|
||||||
|
*(outwalk++) = *walk;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BEGINS_WITH(walk + 1, "time")) {
|
||||||
|
strftime(timebuf, sizeof(timebuf), format_time, &tm);
|
||||||
|
maybe_escape_markup(timebuf, &outwalk);
|
||||||
|
walk += strlen("time");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*outwalk = '\0';
|
*outwalk = '\0';
|
||||||
OUTPUT_FULL_TEXT(buffer);
|
OUTPUT_FULL_TEXT(buffer);
|
||||||
}
|
}
|
||||||
|
@ -519,7 +519,7 @@ void print_wireless_info(yajl_gen json_gen, char *buffer, const char *interface,
|
|||||||
|
|
||||||
if (BEGINS_WITH(walk + 1, "essid")) {
|
if (BEGINS_WITH(walk + 1, "essid")) {
|
||||||
if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID)
|
if (info.flags & WIRELESS_INFO_FLAG_HAS_ESSID)
|
||||||
outwalk += sprintf(outwalk, "%s", info.essid);
|
maybe_escape_markup(info.essid, &outwalk);
|
||||||
else
|
else
|
||||||
*(outwalk++) = '?';
|
*(outwalk++) = '?';
|
||||||
walk += strlen("essid");
|
walk += strlen("essid");
|
||||||
|
Loading…
Reference in New Issue
Block a user