Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/lml.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@

#include <stddef.h>

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_
2 changes: 1 addition & 1 deletion src/article_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/article_post.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
76 changes: 44 additions & 32 deletions src/lml.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -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
Expand All @@ -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)", "", ""},
Expand All @@ -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];
Expand All @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -269,46 +280,47 @@ 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++;
}
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)
Expand All @@ -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
{
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions src/test_lml.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[])
{
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand Down