diff --git a/include/lml.h b/include/lml.h index 16897318..14498569 100644 --- a/include/lml.h +++ b/include/lml.h @@ -19,6 +19,6 @@ #include -extern int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag); +extern int lml_render(const char *str_in, char *str_out, int buf_len, int quote_mode); #endif //_LML_H_ diff --git a/src/article_cache.c b/src/article_cache.c index ac4ba2cb..4bf59c77 100644 --- a/src/article_cache.c +++ b/src/article_cache.c @@ -135,7 +135,7 @@ int article_cache_generate(const char *cache_dir, const ARTICLE *p_article, cons } // Apply LML render to content body - cache.data_len = header_len + (size_t)lml_plain(content, content_f, ARTICLE_CONTENT_MAX_LEN, 1); + cache.data_len = header_len + (size_t)lml_render(content, content_f, ARTICLE_CONTENT_MAX_LEN, 1); cache.line_total = header_line_cnt + split_data_lines(content_f, SCREEN_COLS, cache.line_offsets + header_line_cnt, MAX_SPLIT_FILE_LINES - header_line_cnt, 1, NULL); diff --git a/src/article_post.c b/src/article_post.c index c067d3c7..3677f112 100644 --- a/src/article_post.c +++ b/src/article_post.c @@ -837,7 +837,7 @@ int article_reply(const SECTION_LIST *p_section, const ARTICLE *p_article, ARTIC } // Apply LML render to content body - len = lml_plain(row[1], content_f, ARTICLE_CONTENT_MAX_LEN, 0); + len = lml_render(row[1], content_f, ARTICLE_CONTENT_MAX_LEN, 0); content_f[len] = '\0'; // Remove control sequence diff --git a/src/lml.c b/src/lml.c index 971dc4c1..002e7a42 100644 --- a/src/lml.c +++ b/src/lml.c @@ -24,7 +24,7 @@ #define LML_TAG_PARAM_BUF_LEN 256 #define LML_TAG_OUTPUT_BUF_LEN 1024 -typedef int (*lml_tag_filter_cb)(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len); +typedef int (*lml_tag_filter_cb)(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len, int quote_mode); static int lml_tag_color_filter(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len) { @@ -73,7 +73,7 @@ static const char *lml_tag_quote_color[] = { static int lml_tag_quote_level = 0; -static int lml_tag_quote_filter(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len) +static int lml_tag_quote_filter(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len, int quote_mode) { if (strcasecmp(tag_name, "quote") == 0) { @@ -97,8 +97,18 @@ static int lml_tag_quote_filter(const char *tag_name, const char *tag_param_buf, return 0; } -const static char *LML_tag_def[][4] = { - // Definition of tuple: {lml_tag, lml_output, default_param | lml_filter_cb, no_lml_output} +static int lml_tag_disabled = 0; + +static int lml_tag_disable_filter(const char *tag_name, const char *tag_param_buf, char *tag_output_buf, size_t tag_output_buf_len, int quote_mode) +{ + lml_tag_disabled = 1; + + return snprintf(tag_output_buf, tag_output_buf_len, "%s", (quote_mode ? "" : "[plain]")); +} + +const static char *lml_tag_def[][4] = { + // Definition of tuple: {lml_tag, lml_output, default_param | lml_filter_cb, quote_mode_output} + {"plain", NULL, (const char *)lml_tag_disable_filter, NULL}, {"left", "[", "", "[left]"}, {"right", "]", "", "[right]"}, {"bold", "\033[1m", "", ""}, // does not work in Fterm @@ -119,13 +129,13 @@ const static char *LML_tag_def[][4] = { {"/quote", NULL, (const char *)lml_tag_quote_filter, ""}, {"url", "", "", ""}, {"/url", "(链接: %s)", NULL, ""}, - {"link", "", ""}, + {"link", "", "", ""}, {"/link", "(链接: %s)", NULL, ""}, - {"email", "", ""}, + {"email", "", "", ""}, {"/email", "(Email: %s)", NULL, ""}, - {"user", "", ""}, + {"user", "", "", ""}, {"/user", "(用户: %s)", NULL, ""}, - {"article", "", ""}, + {"article", "", "", ""}, {"/article", "(文章: %s)", NULL, ""}, {"image", "(图片: %s)", "", "%s"}, {"flash", "(Flash: %s)", "", ""}, @@ -134,25 +144,25 @@ const static char *LML_tag_def[][4] = { #define LML_TAG_COUNT 31 -static int LML_tag_name_len[LML_TAG_COUNT]; -static int LML_init = 0; +static int lml_tag_name_len[LML_TAG_COUNT]; +static int lml_ready = 0; inline static void lml_init(void) { int i; - if (!LML_init) + if (!lml_ready) { for (i = 0; i < LML_TAG_COUNT; i++) { - LML_tag_name_len[i] = (int)strlen(LML_tag_def[i][0]); + lml_tag_name_len[i] = (int)strlen(lml_tag_def[i][0]); } - LML_init = 1; + lml_ready = 1; } } -int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) +int lml_render(const char *str_in, char *str_out, int buf_len, int quote_mode) { char c; char tag_param_buf[LML_TAG_PARAM_BUF_LEN]; @@ -169,11 +179,12 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) lml_init(); + lml_tag_disabled = 0; lml_tag_quote_level = 0; for (i = 0; str_in[i] != '\0'; i++) { - if (lml_tag && new_line) + if (quote_mode && !lml_tag_disabled && new_line) { if (fb_quote_level > 0) { @@ -251,11 +262,11 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) continue; // ignore '\r' } - if (str_in[i] == '[') + if (!lml_tag_disabled && str_in[i] == '[') { tag_start_pos = i + 1; } - else if (str_in[i] == ']') + else if (!lml_tag_disabled && str_in[i] == ']') { if (tag_start_pos >= 0) { @@ -269,13 +280,13 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) for (k = 0; k < LML_TAG_COUNT; k++) { - if (strncasecmp(LML_tag_def[k][0], str_in + tag_start_pos, (size_t)LML_tag_name_len[k]) == 0) + if (strncasecmp(lml_tag_def[k][0], str_in + tag_start_pos, (size_t)lml_tag_name_len[k]) == 0) { tag_param_pos = -1; - switch (str_in[tag_start_pos + LML_tag_name_len[k]]) + switch (str_in[tag_start_pos + lml_tag_name_len[k]]) { case ' ': - tag_param_pos = tag_start_pos + LML_tag_name_len[k] + 1; + tag_param_pos = tag_start_pos + lml_tag_name_len[k] + 1; while (str_in[tag_param_pos] == ' ') { tag_param_pos++; @@ -283,32 +294,33 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) strncpy(tag_param_buf, str_in + tag_param_pos, (size_t)MIN(tag_end_pos - tag_param_pos, LML_TAG_PARAM_BUF_LEN)); tag_param_buf[MIN(tag_end_pos - tag_param_pos, LML_TAG_PARAM_BUF_LEN)] = '\0'; case ']': - if (tag_param_pos == -1 && LML_tag_def[k][1] != NULL && LML_tag_def[k][2] != NULL) // Apply default param if not defined + if (tag_param_pos == -1 && lml_tag_def[k][1] != NULL && lml_tag_def[k][2] != NULL) // Apply default param if not defined { - strncpy(tag_param_buf, LML_tag_def[k][2], LML_TAG_PARAM_BUF_LEN - 1); + strncpy(tag_param_buf, lml_tag_def[k][2], LML_TAG_PARAM_BUF_LEN - 1); tag_param_buf[LML_TAG_PARAM_BUF_LEN - 1] = '\0'; } - if (lml_tag) + if (quote_mode) { - if (LML_tag_def[k][1] != NULL) + if (lml_tag_def[k][1] != NULL) { - tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, LML_tag_def[k][1], tag_param_buf); + tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, lml_tag_def[k][1], tag_param_buf); } else { - tag_output_len = ((lml_tag_filter_cb)LML_tag_def[k][2])( - LML_tag_def[k][0], tag_param_buf, tag_output_buf, LML_TAG_OUTPUT_BUF_LEN); + tag_output_len = ((lml_tag_filter_cb)lml_tag_def[k][2])( + lml_tag_def[k][0], tag_param_buf, tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, quote_mode); } } else { - if (LML_tag_def[k][3] != NULL) + if (lml_tag_def[k][3] != NULL) { - tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, LML_tag_def[k][3], tag_param_buf); + tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, lml_tag_def[k][3], tag_param_buf); } else { - tag_output_len = 0; + tag_output_len = ((lml_tag_filter_cb)lml_tag_def[k][2])( + lml_tag_def[k][0], tag_param_buf, tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, quote_mode); } } if (j + tag_output_len >= buf_len) @@ -330,7 +342,7 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) tag_start_pos = -1; } } - else if (tag_start_pos == -1) // not in LML tag + else if (lml_tag_disabled || tag_start_pos == -1) // not in LML tag { if (str_in[i] & 0b10000000) // head of multi-byte character { @@ -368,7 +380,7 @@ int lml_plain(const char *str_in, char *str_out, int buf_len, int lml_tag) } } - if (lml_tag && lml_tag_quote_level > 0) + if (quote_mode && !lml_tag_disabled && lml_tag_quote_level > 0) { tag_output_len = snprintf(tag_output_buf, LML_TAG_OUTPUT_BUF_LEN, "\033[m"); if (j + tag_output_len >= buf_len) diff --git a/src/test_lml.c b/src/test_lml.c index f6e969b5..548470c4 100644 --- a/src/test_lml.c +++ b/src/test_lml.c @@ -39,9 +39,10 @@ const char *str_in[] = { ": ABCDE[quote]FG\r\nab[/quote]cd[quote]ef[quote]g\r\n: : 012[/quote]345[/quote]6789\nABC[quote]DEFG", "abc", "123456", + "[color red]Red[/color][plain][color blue]Blue[/color][plain]", }; -int str_cnt = 15; +int str_cnt = 16; int main(int argc, char *argv[]) { @@ -61,7 +62,7 @@ int main(int argc, char *argv[]) printf("Test #1: lml_tag = 1\n"); for (i = 0; i < str_cnt; i++) { - j = lml_plain(str_in[i], str_out_buf, sizeof(str_out_buf), 1); + j = lml_render(str_in[i], str_out_buf, sizeof(str_out_buf), 1); printf("Input(len=%ld): %s\nOutput(len=%d): %s\n", strlen(str_in[i]), str_in[i], j, str_out_buf); } @@ -70,7 +71,7 @@ int main(int argc, char *argv[]) printf("Test #2: lml_tag = 0\n"); for (i = 0; i < str_cnt; i++) { - j = lml_plain(str_in[i], str_out_buf, sizeof(str_out_buf), 0); + j = lml_render(str_in[i], str_out_buf, sizeof(str_out_buf), 0); printf("Input(len=%ld): %s\nOutput(len=%d): %s\n", strlen(str_in[i]), str_in[i], j, str_out_buf); }