[markdown] some minor improvements

pull/1179/head
Tim Stack 11 months ago
parent b2bd2bf8c9
commit 4b9f81a65a

@ -44,6 +44,11 @@ Features:
variables are now defined inside **lnav** and refer to variables are now defined inside **lnav** and refer to
the location of the user's configuration directory and the location of the user's configuration directory and
the directory where cached data is stored, respectively. the directory where cached data is stored, respectively.
* The `<pre>` tag is now recognized in Markdown files.
* The `style` attribute in `<span>` tags is now supported.
Basic properties like `color`, `background-color`,
`font-weight`, and `text-decoration` can be used. CSS
color names should work as well.
Bug Fixes: Bug Fixes:
* Binary data piped into stdin should now be treated the same * Binary data piped into stdin should now be treated the same

@ -103,7 +103,7 @@ function(bin2c)
DEPENDS bin2c "${FILE_TO_LINK}") DEPENDS bin2c "${FILE_TO_LINK}")
endfunction(bin2c) endfunction(bin2c)
foreach (FILE_TO_LINK animals.json ansi-palette.json diseases.json emojis.json xml-entities.json xterm-palette.json help.txt help.md init.sql words.json) foreach (FILE_TO_LINK animals.json ansi-palette.json css-color-names.json diseases.json emojis.json xml-entities.json xterm-palette.json help.txt help.md init.sql words.json)
string(REPLACE "." "-" DST_FILE "${FILE_TO_LINK}") string(REPLACE "." "-" DST_FILE "${FILE_TO_LINK}")
add_custom_command( add_custom_command(
OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc" OUTPUT "${DST_FILE}.h" "${DST_FILE}.cc"
@ -196,7 +196,7 @@ set(BUILTIN_LNAV_SCRIPTS
scripts/partition-by-boot.lnav scripts/rename-stdin.lnav scripts/partition-by-boot.lnav scripts/rename-stdin.lnav
scripts/search-for.lnav scripts/search-for.lnav
scripts/workdir-url-handler.lnav scripts/workdir-url-handler.lnav
) )
set(BUILTIN_LNAV_SCRIPT_PATHS ${BUILTIN_LNAV_SCRIPTS}) set(BUILTIN_LNAV_SCRIPT_PATHS ${BUILTIN_LNAV_SCRIPTS})
@ -328,7 +328,7 @@ add_library(lnavfileio STATIC
line_buffer.cc line_buffer.cc
pollable.cc pollable.cc
shared_buffer.cc shared_buffer.cc
) )
target_include_directories(lnavfileio PRIVATE . ${CMAKE_CURRENT_BINARY_DIR}) target_include_directories(lnavfileio PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(lnavfileio cppfmt spookyhash pcrepp base BZip2::BZip2 ZLIB::ZLIB) target_link_libraries(lnavfileio cppfmt spookyhash pcrepp base BZip2::BZip2 ZLIB::ZLIB)
@ -612,7 +612,7 @@ target_include_directories(diag PUBLIC . fmtlib ${CMAKE_CURRENT_BINARY_DIR}
third-party third-party
third-party/base64/include third-party/base64/include
third-party/rapidyaml third-party/rapidyaml
) )
target_link_libraries( target_link_libraries(
diag diag

@ -95,6 +95,7 @@ LNAV_BUILT_FILES = \
ansi-palette-json.cc \ ansi-palette-json.cc \
builtin-scripts.cc \ builtin-scripts.cc \
builtin-sh-scripts.cc \ builtin-sh-scripts.cc \
css-color-names-json.cc \
default-config.cc \ default-config.cc \
default-formats.cc \ default-formats.cc \
diseases-json.cc \ diseases-json.cc \
@ -158,11 +159,13 @@ LDADD = \
# emojis.json is from https://gist.github.com/oliveratgithub/0bf11a9aff0d6da7b46f1490f86a71eb/ # emojis.json is from https://gist.github.com/oliveratgithub/0bf11a9aff0d6da7b46f1490f86a71eb/
# xml-entities.json is from https://html.spec.whatwg.org/entities.json # xml-entities.json is from https://html.spec.whatwg.org/entities.json
# css-color-names.json is from https://github.com/bahamas10/css-color-names/blob/master/css-color-names.json
dist_noinst_DATA = \ dist_noinst_DATA = \
alpha-release.sh \ alpha-release.sh \
animals.json \ animals.json \
ansi-palette.json \ ansi-palette.json \
css-color-names.json \
diseases.json \ diseases.json \
emojis.json \ emojis.json \
$(BUILTIN_LNAVSCRIPTS) \ $(BUILTIN_LNAVSCRIPTS) \
@ -524,6 +527,7 @@ DISTCLEANFILES = \
ansi-palette-json.h \ ansi-palette-json.h \
builtin-scripts.h \ builtin-scripts.h \
builtin-sh-scripts.h \ builtin-sh-scripts.h \
css-color-names-json.h \
default-config.h \ default-config.h \
default-formats.h \ default-formats.h \
diseases-json.h \ diseases-json.h \

@ -242,8 +242,8 @@ scrub_ansi_string(std::string& str, string_attrs_t* sa)
auto seq = md[1].value(); auto seq = md[1].value();
auto terminator = md[2].value(); auto terminator = md[2].value();
struct line_range lr; struct line_range lr;
bool has_attrs = false;
text_attrs attrs; text_attrs attrs;
bool has_attrs = false;
nonstd::optional<role_t> role; nonstd::optional<role_t> role;
size_t lpc; size_t lpc;
@ -349,7 +349,7 @@ scrub_ansi_string(std::string& str, string_attrs_t* sa)
} }
lr.lr_start = sf.sf_begin; lr.lr_start = sf.sf_begin;
lr.lr_end = -1; lr.lr_end = -1;
if (attrs.ta_attrs || attrs.ta_fg_color || attrs.ta_bg_color) { if (!attrs.empty()) {
sa->emplace_back(lr, VC_STYLE.value(attrs)); sa->emplace_back(lr, VC_STYLE.value(attrs));
} }
role | [&lr, &sa](role_t r) { role | [&lr, &sa](role_t r) {

@ -115,6 +115,16 @@ trim(const std::string& str)
return str.substr(start, end - start); return str.substr(start, end - start);
} }
inline const char*
ltrim(const char* str)
{
while (isspace(*str)) {
str += 1;
}
return str;
}
inline std::string inline std::string
rtrim(const std::string& str) rtrim(const std::string& str)
{ {

@ -0,0 +1,150 @@
{
"aliceblue": "#f0f8ff",
"antiquewhite": "#faebd7",
"aqua": "#00ffff",
"aquamarine": "#7fffd4",
"azure": "#f0ffff",
"beige": "#f5f5dc",
"bisque": "#ffe4c4",
"black": "#000000",
"blanchedalmond": "#ffebcd",
"blue": "#0000ff",
"blueviolet": "#8a2be2",
"brown": "#a52a2a",
"burlywood": "#deb887",
"cadetblue": "#5f9ea0",
"chartreuse": "#7fff00",
"chocolate": "#d2691e",
"coral": "#ff7f50",
"cornflowerblue": "#6495ed",
"cornsilk": "#fff8dc",
"crimson": "#dc143c",
"cyan": "#00ffff",
"darkblue": "#00008b",
"darkcyan": "#008b8b",
"darkgoldenrod": "#b8860b",
"darkgray": "#a9a9a9",
"darkgreen": "#006400",
"darkgrey": "#a9a9a9",
"darkkhaki": "#bdb76b",
"darkmagenta": "#8b008b",
"darkolivegreen": "#556b2f",
"darkorange": "#ff8c00",
"darkorchid": "#9932cc",
"darkred": "#8b0000",
"darksalmon": "#e9967a",
"darkseagreen": "#8fbc8f",
"darkslateblue": "#483d8b",
"darkslategray": "#2f4f4f",
"darkslategrey": "#2f4f4f",
"darkturquoise": "#00ced1",
"darkviolet": "#9400d3",
"deeppink": "#ff1493",
"deepskyblue": "#00bfff",
"dimgray": "#696969",
"dimgrey": "#696969",
"dodgerblue": "#1e90ff",
"firebrick": "#b22222",
"floralwhite": "#fffaf0",
"forestgreen": "#228b22",
"fuchsia": "#ff00ff",
"gainsboro": "#dcdcdc",
"ghostwhite": "#f8f8ff",
"goldenrod": "#daa520",
"gold": "#ffd700",
"gray": "#808080",
"green": "#008000",
"greenyellow": "#adff2f",
"grey": "#808080",
"honeydew": "#f0fff0",
"hotpink": "#ff69b4",
"indianred": "#cd5c5c",
"indigo": "#4b0082",
"ivory": "#fffff0",
"khaki": "#f0e68c",
"lavenderblush": "#fff0f5",
"lavender": "#e6e6fa",
"lawngreen": "#7cfc00",
"lemonchiffon": "#fffacd",
"lightblue": "#add8e6",
"lightcoral": "#f08080",
"lightcyan": "#e0ffff",
"lightgoldenrodyellow": "#fafad2",
"lightgray": "#d3d3d3",
"lightgreen": "#90ee90",
"lightgrey": "#d3d3d3",
"lightpink": "#ffb6c1",
"lightsalmon": "#ffa07a",
"lightseagreen": "#20b2aa",
"lightskyblue": "#87cefa",
"lightslategray": "#778899",
"lightslategrey": "#778899",
"lightsteelblue": "#b0c4de",
"lightyellow": "#ffffe0",
"lime": "#00ff00",
"limegreen": "#32cd32",
"linen": "#faf0e6",
"magenta": "#ff00ff",
"maroon": "#800000",
"mediumaquamarine": "#66cdaa",
"mediumblue": "#0000cd",
"mediumorchid": "#ba55d3",
"mediumpurple": "#9370db",
"mediumseagreen": "#3cb371",
"mediumslateblue": "#7b68ee",
"mediumspringgreen": "#00fa9a",
"mediumturquoise": "#48d1cc",
"mediumvioletred": "#c71585",
"midnightblue": "#191970",
"mintcream": "#f5fffa",
"mistyrose": "#ffe4e1",
"moccasin": "#ffe4b5",
"navajowhite": "#ffdead",
"navy": "#000080",
"oldlace": "#fdf5e6",
"olive": "#808000",
"olivedrab": "#6b8e23",
"orange": "#ffa500",
"orangered": "#ff4500",
"orchid": "#da70d6",
"palegoldenrod": "#eee8aa",
"palegreen": "#98fb98",
"paleturquoise": "#afeeee",
"palevioletred": "#db7093",
"papayawhip": "#ffefd5",
"peachpuff": "#ffdab9",
"peru": "#cd853f",
"pink": "#ffc0cb",
"plum": "#dda0dd",
"powderblue": "#b0e0e6",
"purple": "#800080",
"rebeccapurple": "#663399",
"red": "#ff0000",
"rosybrown": "#bc8f8f",
"royalblue": "#4169e1",
"saddlebrown": "#8b4513",
"salmon": "#fa8072",
"sandybrown": "#f4a460",
"seagreen": "#2e8b57",
"seashell": "#fff5ee",
"sienna": "#a0522d",
"silver": "#c0c0c0",
"skyblue": "#87ceeb",
"slateblue": "#6a5acd",
"slategray": "#708090",
"slategrey": "#708090",
"snow": "#fffafa",
"springgreen": "#00ff7f",
"steelblue": "#4682b4",
"tan": "#d2b48c",
"teal": "#008080",
"thistle": "#d8bfd8",
"tomato": "#ff6347",
"turquoise": "#40e0d0",
"violet": "#ee82ee",
"wheat": "#f5deb3",
"white": "#ffffff",
"whitesmoke": "#f5f5f5",
"yellow": "#ffff00",
"yellowgreen": "#9acd32"
}

@ -474,6 +474,9 @@ field_overlay_source::build_meta_line(const listview_curses& lv,
} }
auto comment_lines = al.rtrim().split_lines(); auto comment_lines = al.rtrim().split_lines();
if (comment_lines.back().empty()) {
comment_lines.pop_back();
}
for (size_t lpc = 0; lpc < comment_lines.size(); lpc++) { for (size_t lpc = 0; lpc < comment_lines.size(); lpc++) {
auto& comment_line = comment_lines[lpc]; auto& comment_line = comment_lines[lpc];

@ -488,11 +488,129 @@ md2attr_line::leave_span(const md4cpp::event_handler::span& sp)
return Ok(); return Ok();
} }
static attr_line_t
to_attr_line(const pugi::xml_node& doc)
{
static const auto NAME_SPAN = string_fragment::from_const("span");
static const auto NAME_PRE = string_fragment::from_const("pre");
static const auto NAME_FG = string_fragment::from_const("color");
static const auto NAME_BG = string_fragment::from_const("background-color");
static const auto NAME_FONT_WEIGHT
= string_fragment::from_const("font-weight");
static const auto NAME_TEXT_DECO
= string_fragment::from_const("text-decoration");
static const auto& vc = view_colors::singleton();
attr_line_t retval;
if (doc.children().empty()) {
retval.append(doc.text().get());
}
for (const auto& child : doc.children()) {
if (child.name() == NAME_SPAN) {
auto styled_span = attr_line_t(child.text().get());
auto span_class = child.attribute("class");
if (span_class) {
auto cl_iter = vc.vc_class_to_role.find(span_class.value());
if (cl_iter == vc.vc_class_to_role.end()) {
log_error("unknown span class: %s", span_class.value());
} else {
styled_span.with_attr_for_all(cl_iter->second);
}
}
text_attrs ta;
auto span_style = child.attribute("style");
if (span_style) {
auto style_sf = string_fragment::from_c_str(span_style.value());
while (!style_sf.empty()) {
auto split_res
= style_sf.split_when(string_fragment::tag1{';'});
auto colon_split_res = split_res.first.split_pair(
string_fragment::tag1{':'});
if (colon_split_res) {
auto key = colon_split_res->first.trim();
auto value = colon_split_res->second.trim();
if (key == NAME_FG) {
auto color_res
= styling::color_unit::from_str(value);
if (color_res.isErr()) {
log_error("invalid color: %.*s -- %s",
value.length(),
value.data(),
color_res.unwrapErr().c_str());
} else {
ta.ta_fg_color
= vc.match_color(color_res.unwrap());
}
} else if (key == NAME_BG) {
auto color_res
= styling::color_unit::from_str(value);
if (color_res.isErr()) {
log_error(
"invalid background-color: %.*s -- %s",
value.length(),
value.data(),
color_res.unwrapErr().c_str());
} else {
ta.ta_bg_color
= vc.match_color(color_res.unwrap());
}
} else if (key == NAME_FONT_WEIGHT) {
if (value == "bold" || value == "bolder") {
ta.ta_attrs |= A_BOLD;
}
} else if (key == NAME_TEXT_DECO) {
auto deco_sf = value;
while (!deco_sf.empty()) {
auto deco_split_res = deco_sf.split_when(
string_fragment::tag1{' '});
if (deco_split_res.first.trim() == "underline")
{
ta.ta_attrs |= A_UNDERLINE;
}
deco_sf = deco_split_res.second;
}
}
}
style_sf = split_res.second;
}
if (!ta.empty()) {
styled_span.with_attr_for_all(VC_STYLE.value(ta));
}
}
retval.append(styled_span);
} else if (child.name() == NAME_PRE) {
auto pre_al = attr_line_t();
for (const auto& sub : child.children()) {
auto child_al = to_attr_line(sub);
if (pre_al.empty() && startswith(child_al.get_string(), "\n")) {
child_al.erase(0, 1);
}
pre_al.append(child_al);
}
pre_al.with_attr_for_all(SA_PREFORMATTED.value());
retval.append(pre_al);
} else {
retval.append(child.text().get());
}
}
return retval;
}
Result<void, std::string> Result<void, std::string>
md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf) md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf)
{ {
static const auto& entity_map = md4cpp::get_xml_entity_map(); static const auto& entity_map = md4cpp::get_xml_entity_map();
static const auto& vc = view_colors::singleton();
auto& last_block = this->ml_blocks.back(); auto& last_block = this->ml_blocks.back();
@ -517,40 +635,64 @@ md2attr_line::text(MD_TEXTTYPE tt, const string_fragment& sf)
} }
case MD_TEXT_HTML: { case MD_TEXT_HTML: {
last_block.append(sf); last_block.append(sf);
if (sf.startswith("<span ")) {
this->ml_html_span_starts.push_back(last_block.length() struct open_tag {
- sf.length()); std::string ot_name;
} else if (sf == "</span>" && !this->ml_html_span_starts.empty()) { };
std::string html_span = last_block.get_string().substr( struct close_tag {
this->ml_html_span_starts.back()); std::string ct_name;
};
pugi::xml_document doc;
mapbox::util::variant<open_tag, close_tag> tag;
auto load_res = doc.load_string(html_span.c_str());
if (load_res) { if (sf.startswith("</")) {
auto span = doc.child("span"); tag = close_tag{
if (span) { sf.substr(2)
auto styled_span = attr_line_t(span.text().get()); .split_when(string_fragment::tag1{'>'})
.first.to_string(),
auto span_class = span.attribute("class"); };
if (span_class) { } else if (sf.startswith("<")) {
auto cl_iter tag = open_tag{
= vc.vc_class_to_role.find(span_class.value()); sf.substr(1)
.split_when(
if (cl_iter == vc.vc_class_to_role.end()) { [](char ch) { return ch == ' ' || ch == '>'; })
log_error("unknown span class: %s", .first.to_string(),
span_class.value()); };
} else { }
styled_span.with_attr_for_all(cl_iter->second);
} if (tag.valid()) {
tag.match(
[this, &sf, &last_block](const open_tag& ot) {
if (!this->ml_html_starts.empty()) {
return;
} }
last_block.erase(this->ml_html_span_starts.back()); this->ml_html_starts.emplace_back(
last_block.append(styled_span); ot.ot_name, last_block.length() - sf.length());
} },
} else { [this, &last_block](const close_tag& ct) {
log_error("failed to parse: %s", load_res.description()); if (this->ml_html_starts.empty()) {
} return;
this->ml_html_span_starts.pop_back(); }
if (this->ml_html_starts.back().first != ct.ct_name) {
return;
}
const auto html_span = last_block.get_string().substr(
this->ml_html_starts.back().second);
pugi::xml_document doc;
auto load_res = doc.load_string(html_span.c_str());
if (!load_res) {
log_error("failed to parse: %s",
load_res.description());
} else {
last_block.erase(
this->ml_html_starts.back().second);
last_block.append(to_attr_line(doc));
}
this->ml_html_starts.pop_back();
});
} }
break; break;
} }

@ -83,7 +83,7 @@ private:
std::vector<list_block_t> ml_list_stack; std::vector<list_block_t> ml_list_stack;
std::vector<table_t> ml_tables; std::vector<table_t> ml_tables;
std::vector<size_t> ml_span_starts; std::vector<size_t> ml_span_starts;
std::vector<size_t> ml_html_span_starts; std::vector<std::pair<std::string, size_t>> ml_html_starts;
std::vector<attr_line_t> ml_footnotes; std::vector<attr_line_t> ml_footnotes;
int32_t ml_code_depth{0}; int32_t ml_code_depth{0};
}; };

@ -81,7 +81,11 @@ plain_text_source::replace_with(const attr_line_t& text_lines)
this->tds_doc_sections = lnav::document::discover_metadata(text_lines); this->tds_doc_sections = lnav::document::discover_metadata(text_lines);
file_off_t off = 0; file_off_t off = 0;
for (auto& line : text_lines.split_lines()) { auto lines = text_lines.split_lines();
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
for (auto& line : lines) {
auto line_len = line.length() + 1; auto line_len = line.length() + 1;
this->tds_lines.emplace_back(off, std::move(line)); this->tds_lines.emplace_back(off, std::move(line));
off += line_len; off += line_len;

@ -1023,9 +1023,13 @@ annotate_sql_statement(attr_line_t& al)
lnav::pcre2pp::code::from_const(R"(\A'[^']*('(?:'[^']*')*|$))"), lnav::pcre2pp::code::from_const(R"(\A'[^']*('(?:'[^']*')*|$))"),
&SQL_STRING_ATTR, &SQL_STRING_ATTR,
}, },
{
lnav::pcre2pp::code::from_const(R"(\A0x[0-9a-fA-F]+)"),
&SQL_NUMBER_ATTR,
},
{ {
lnav::pcre2pp::code::from_const( lnav::pcre2pp::code::from_const(
R"(\A-?\d+(?:\.\d*(?:[eE][\-\+]?\d+)?)?|0x[0-9a-fA-F]+$)"), R"(\A-?\d+(?:\.\d+)?(?:[eE][\-\+]?\d+)?)"),
&SQL_NUMBER_ATTR, &SQL_NUMBER_ATTR,
}, },
{ {

@ -33,6 +33,7 @@
#include "ansi-palette-json.h" #include "ansi-palette-json.h"
#include "config.h" #include "config.h"
#include "css-color-names-json.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "xterm-palette-json.h" #include "xterm-palette-json.h"
#include "yajlpp/yajlpp.hh" #include "yajlpp/yajlpp.hh"
@ -67,6 +68,29 @@ static const typed_json_path_container<std::vector<term_color>>
.with_children(term_color_handler), .with_children(term_color_handler),
}; };
struct css_color_names {
std::map<std::string, std::string> ccn_name_to_color;
};
static const typed_json_path_container<css_color_names> css_color_names_handlers
= {
yajlpp::pattern_property_handler("(?<css_color_name>.*)")
.for_field(&css_color_names::ccn_name_to_color),
};
static const css_color_names&
get_css_color_names()
{
static const intern_string_t iname
= intern_string::lookup(css_color_names_json.get_name());
static const auto INSTANCE
= css_color_names_handlers.parser_for(iname)
.of(css_color_names_json.to_string_fragment())
.unwrap();
return INSTANCE;
}
term_color_palette* term_color_palette*
xterm_colors() xterm_colors()
{ {
@ -86,12 +110,21 @@ ansi_colors()
} }
Result<rgb_color, std::string> Result<rgb_color, std::string>
rgb_color::from_str(const string_fragment& sf) rgb_color::from_str(string_fragment sf)
{ {
if (sf.empty()) { if (sf.empty()) {
return Ok(rgb_color()); return Ok(rgb_color());
} }
if (sf[0] != '#') {
const auto& css_colors = get_css_color_names();
const auto& iter = css_colors.ccn_name_to_color.find(sf.to_string());
if (iter != css_colors.ccn_name_to_color.end()) {
sf = string_fragment::from_str(iter->second);
}
}
rgb_color rgb_out; rgb_color rgb_out;
if (sf[0] == '#') { if (sf[0] == '#') {

@ -43,7 +43,7 @@
#include "yajlpp/yajlpp_def.hh" #include "yajlpp/yajlpp_def.hh"
struct rgb_color { struct rgb_color {
static Result<rgb_color, std::string> from_str(const string_fragment& sf); static Result<rgb_color, std::string> from_str(string_fragment sf);
explicit rgb_color(short r = -1, short g = -1, short b = -1) explicit rgb_color(short r = -1, short g = -1, short b = -1)
: rc_r(r), rc_g(g), rc_b(b) : rc_r(r), rc_g(g), rc_b(b)

@ -596,6 +596,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_anno.sh_c909647ed0e585002074f55c946f3033df1815b2.out \ $(srcdir)/%reldir%/test_sql_anno.sh_c909647ed0e585002074f55c946f3033df1815b2.out \
$(srcdir)/%reldir%/test_sql_anno.sh_ce0506ee7a12eb0f7b970522cc6a79180ecb20cc.err \ $(srcdir)/%reldir%/test_sql_anno.sh_ce0506ee7a12eb0f7b970522cc6a79180ecb20cc.err \
$(srcdir)/%reldir%/test_sql_anno.sh_ce0506ee7a12eb0f7b970522cc6a79180ecb20cc.out \ $(srcdir)/%reldir%/test_sql_anno.sh_ce0506ee7a12eb0f7b970522cc6a79180ecb20cc.out \
$(srcdir)/%reldir%/test_sql_anno.sh_de46094b6e005285dc0921ef9979e36240c5042d.err \
$(srcdir)/%reldir%/test_sql_anno.sh_de46094b6e005285dc0921ef9979e36240c5042d.out \
$(srcdir)/%reldir%/test_sql_anno.sh_f3c64191d6016767a5857fbb1bad26548586bb96.err \ $(srcdir)/%reldir%/test_sql_anno.sh_f3c64191d6016767a5857fbb1bad26548586bb96.err \
$(srcdir)/%reldir%/test_sql_anno.sh_f3c64191d6016767a5857fbb1bad26548586bb96.out \ $(srcdir)/%reldir%/test_sql_anno.sh_f3c64191d6016767a5857fbb1bad26548586bb96.out \
$(srcdir)/%reldir%/test_sql_coll_func.sh_077cab6e271c914daf5b221cc512853077891f35.err \ $(srcdir)/%reldir%/test_sql_coll_func.sh_077cab6e271c914daf5b221cc512853077891f35.err \
@ -1064,6 +1066,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_text_file.sh_ac872aadda29b9a824361a2c711d62ec1c75d40f.out \ $(srcdir)/%reldir%/test_text_file.sh_ac872aadda29b9a824361a2c711d62ec1c75d40f.out \
$(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.err \ $(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.err \
$(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.out \ $(srcdir)/%reldir%/test_text_file.sh_c2a346ca1da2da4346f1d310212e166767993ce9.out \
$(srcdir)/%reldir%/test_text_file.sh_d59b67113864ef5e77267d7fd8ad4072f5aef0fc.err \
$(srcdir)/%reldir%/test_text_file.sh_d59b67113864ef5e77267d7fd8ad4072f5aef0fc.out \
$(srcdir)/%reldir%/test_text_file.sh_e088ea61a5382458cc48a2607e2639e52b0be1da.err \ $(srcdir)/%reldir%/test_text_file.sh_e088ea61a5382458cc48a2607e2639e52b0be1da.err \
$(srcdir)/%reldir%/test_text_file.sh_e088ea61a5382458cc48a2607e2639e52b0be1da.out \ $(srcdir)/%reldir%/test_text_file.sh_e088ea61a5382458cc48a2607e2639e52b0be1da.out \
$() $()

@ -2086,7 +2086,7 @@ For support questions, email:
unparse_url(), upper(), xpath() unparse_url(), upper(), xpath()
Example Example
#1 To get a string with the code points 0x48 and 0x49: #1 To get a string with the code points 0x48 and 0x49:
;SELECT char(0x48, 0x49)  ;SELECT char(0x48, 0x49) 
@ -4807,4 +4807,3 @@ For support questions, email:
cte-table-name The name for the temporary table. cte-table-name The name for the temporary table.
select-stmt The SELECT statement used to select-stmt The SELECT statement used to
populate the temporary table. populate the temporary table.

@ -0,0 +1,7 @@
SELECT 0x77, 123, 123e4
sql_keyword ------
sql_number ----
sql_comma -
sql_number ---
sql_comma -
sql_number -----

@ -16,4 +16,3 @@ command-line. If you're familiar with the SumoLogic query language,
you might find this tool more comfortable to work with. you might find this tool more comfortable to work with.
▌[1] - https://github.com/rcoh/angle-grinder ▌[1] - https://github.com/rcoh/angle-grinder

@ -175,4 +175,3 @@ command-line. If you're familiar with the SumoLogic query language,
you might find this tool more comfortable to work with. you might find this tool more comfortable to work with.
▌[1] - https://github.com/rcoh/angle-grinder ▌[1] - https://github.com/rcoh/angle-grinder

@ -146,4 +146,3 @@ command-line. If you're familiar with the SumoLogic query language,
you might find this tool more comfortable to work with. you might find this tool more comfortable to work with.
▌[1] - https://github.com/rcoh/angle-grinder ▌[1] - https://github.com/rcoh/angle-grinder

@ -1,4 +1,4 @@
command-line. If you're familiar with the SumoLogic query language,
you might find this tool more comfortable to work with. you might find this tool more comfortable to work with.
▌[1] - https://github.com/rcoh/angle-grinder ▌[1] - https://github.com/rcoh/angle-grinder

@ -0,0 +1,13 @@
Test
• One
• Two
• Three
Bold red
Underline
Hello,
World!

@ -146,4 +146,3 @@ command-line. If you're familiar with the SumoLogic query language,
you might find this tool more comfortable to work with. you might find this tool more comfortable to work with.
▌[1] - https://github.com/rcoh/angle-grinder ▌[1] - https://github.com/rcoh/angle-grinder

@ -50,3 +50,5 @@ run_cap_test ./drive_sql_anno \
run_cap_test ./drive_sql_anno "SELECT * FROM foo.bar" run_cap_test ./drive_sql_anno "SELECT * FROM foo.bar"
run_cap_test ./drive_sql_anno "SELECT json_object('abc', 'def') ->> '$.abc'" run_cap_test ./drive_sql_anno "SELECT json_object('abc', 'def') ->> '$.abc'"
run_cap_test ./drive_sql_anno "SELECT 0x77, 123, 123e4"

@ -34,3 +34,6 @@ run_cap_test ${lnav_test} -n \
run_cap_test ${lnav_test} -n \ run_cap_test ${lnav_test} -n \
${test_dir}/textfile_ansi_expanding.0 ${test_dir}/textfile_ansi_expanding.0
run_cap_test ${lnav_test} -n \
${test_dir}/textfile_0.md

@ -7,3 +7,12 @@
* One * One
* Two * Two
* Three * Three
<span style="color: #f00; font-weight: bold">Bold red</span>
<span style="text-decoration: underline; background-color: darkblue">Underline</span>
<pre>
Hello,
<span class="name">World</span>!
</pre>

Loading…
Cancel
Save