Skip to content
Snippets Groups Projects
Commit 9a746495 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add support for Renegade color (pipe) codes to wordwrap()

When viewing messages posted with pipe codes (e.g. coming from Renegade, WWIV,
Mystic BBS), the wordwrap logic would prematurely wrap lines.
parent 1e440ffc
Branches
No related tags found
No related merge requests found
Pipeline #8706 failed
......@@ -1326,6 +1326,7 @@ js_word_wrap(JSContext *cx, uintN argc, jsval *arglist)
int32 oldlen = 79;
JSBool handle_quotes = JS_TRUE;
JSBool is_utf8 = JS_FALSE;
JSBool pipe_codes = JS_FALSE;
char* inbuf = NULL;
char* outbuf;
JSString* js_str;
......@@ -1360,10 +1361,12 @@ js_word_wrap(JSContext *cx, uintN argc, jsval *arglist)
handle_quotes = JSVAL_TO_BOOLEAN(argv[3]);
if (argc > 4 && JSVAL_IS_BOOLEAN(argv[4]))
is_utf8 = JSVAL_TO_BOOLEAN(argv[4]);
if (argc > 5 && JSVAL_IS_BOOLEAN(argv[5]))
pipe_codes = JSVAL_TO_BOOLEAN(argv[5]);
rc = JS_SUSPENDREQUEST(cx);
outbuf = wordwrap(inbuf, len, oldlen, handle_quotes, is_utf8);
outbuf = wordwrap(inbuf, len, oldlen, handle_quotes, is_utf8, pipe_codes);
free(inbuf);
JS_RESUMEREQUEST(cx, rc);
......@@ -5179,10 +5182,10 @@ static jsSyncMethodSpec js_global_functions[] = {
{"html_decode", js_html_decode, 1, JSTYPE_STRING, JSDOCSTR("html")
, JSDOCSTR("Return a decoded HTML-encoded text string, translating HTML character entities into CP437 character equivalents")
, 311},
{"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=79 [,orig_line_length=79 [,<i>bool</i> handle_quotes=true [,<i>bool</i> is_utf8=false]]]]")
{"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=79 [,orig_line_length=79 [,<i>bool</i> handle_quotes=true [,<i>bool</i> is_utf8=false [,<i>bool</i> pipe_codes=false]]]]]")
, JSDOCSTR("Return a word-wrapped version of the <i>text</i> string argument optionally handing quotes magically, "
"<i>line_length</i> defaults to <i>79</i>, <i>orig_line_length</i> defaults to <tt>79</tt>, "
"<i>handle_quotes</i> defaults to <tt>true</tt>, and <i>is_utf8</i> defaults to <tt>false</tt>"
"<i>handle_quotes</i> defaults to <tt>true</tt>, <i>is_utf8</i> defaults to <tt>false</tt>, and <i>pipe_codes</i> (Renegade color codes) defaults to <tt>false</tt>."
"<p>Note: if the original text does not contain any carriage-return (CR) characters, lines are wrapped with sole line-feed (LF) characters.")
, 311},
{"quote_msg", js_quote_msg, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=79] [,prefix=\" > \"]")
......
......@@ -259,7 +259,7 @@ int sbbs_t::msgtoqwk(smbmsg_t* msg, FILE *qwk_fp, int mode, smb_t* smb
if (mode & QM_WORDWRAP) {
int org_cols = msg->columns ? msg->columns : 80;
int new_cols = useron.cols ? useron.cols : cols ? cols : 80;
char* wrapped = ::wordwrap(buf, new_cols - 1, org_cols - 1, /* handle_quotes */ true, is_utf8);
char* wrapped = ::wordwrap(buf, new_cols - 1, org_cols - 1, /* handle_quotes */ true, is_utf8, /* pipe_codes: */false);
if (wrapped != NULL) {
free(buf);
buf = wrapped;
......
......@@ -111,7 +111,8 @@ char sbbs_t::putmsgfrag(const char* buf, int& mode, int org_cols, JSObject* obj)
if (org_cols < TERM_COLS_MIN)
org_cols = TERM_COLS_DEFAULT;
if ((wrapped = ::wordwrap((char*)str + l, cols - 1, org_cols - 1, /* handle_quotes: */ TRUE
, /* is_utf8: */ INT_TO_BOOL(mode & P_UTF8))) == NULL)
, /* is_utf8: */ INT_TO_BOOL(mode & P_UTF8)
, /* pipe_codes: */(cfg.sys_misc & SM_RENEGADE) && !INT_TO_BOOL(mode & P_NOXATTRS))) == NULL)
errormsg(WHERE, ERR_ALLOC, "wordwrap buffer", 0);
else {
truncsp_lines(wrapped);
......
......@@ -223,7 +223,7 @@ static struct section_len get_ws_len(char *buf, int col)
* maxlen cols (used to find the number of bytes to fill a specific
* number of columns).
*/
static struct section_len get_word_len(char *buf, int maxlen, bool is_utf8)
static struct section_len get_word_len(char *buf, int maxlen, bool is_utf8, bool pipe_codes)
{
struct section_len ret = {0, 0};
......@@ -242,6 +242,10 @@ static struct section_len get_word_len(char *buf, int maxlen, bool is_utf8)
break;
continue;
}
else if (pipe_codes && buf[ret.bytes] == '|' && IS_DIGIT(buf[ret.bytes + 1]) && IS_DIGIT(buf[ret.bytes + 2])) {
ret.bytes += 2;
continue;
}
else if (buf[ret.bytes] == '\b') {
// This doesn't handle BS the same way... bit it's kinda BS anyway.
ret.len--;
......@@ -319,7 +323,7 @@ static bool paragraph_append(struct paragraph *paragraph, const char *bytes, siz
* The returned malloc()ed array will have the text member of the last
* paragraph set to NULL.
*/
static struct paragraph *word_unwrap(char *inbuf, int oldlen, bool handle_quotes, bool *has_crs, bool is_utf8)
static struct paragraph *word_unwrap(char *inbuf, int oldlen, bool handle_quotes, bool *has_crs, bool is_utf8, bool pipe_codes)
{
unsigned inpos = 0;
struct prefix new_prefix;
......@@ -419,7 +423,7 @@ static struct paragraph *word_unwrap(char *inbuf, int oldlen, bool handle_quotes
}
// If the first word on the next line would have fit here, it's hard
next_word_len = get_word_len(inbuf + inpos + 1 + new_prefix_len, -1, is_utf8).len;
next_word_len = get_word_len(inbuf + inpos + 1 + new_prefix_len, -1, is_utf8, pipe_codes).len;
if ((incol + next_word_len + 1 - 1) < oldlen) {
FREE_AND_NULL(new_prefix.bytes);
paragraph_done = true;
......@@ -439,6 +443,14 @@ static struct paragraph *word_unwrap(char *inbuf, int oldlen, bool handle_quotes
while (incol % 8)
incol++;
break;
case '|': // Pipe color codes (e.g. from Renegade, WWIV, Mystic)
if (pipe_codes && IS_DIGIT(inbuf[inpos + 1]) && IS_DIGIT(inbuf[inpos + 2])) {
if (!paragraph_append(&ret[paragraph], inbuf + inpos, 3))
goto fail_return;
inpos += 2;
break;
}
// Fall-through
default:
if (!paragraph_append(&ret[paragraph], inbuf + inpos, 1))
goto fail_return;
......@@ -472,7 +484,7 @@ fail_return:
*
* Returns a malloc()ed string.
*/
static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, bool handle_quotes, bool has_crs, bool is_utf8)
static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, bool handle_quotes, bool has_crs, bool is_utf8, bool pipe_codes)
{
int outcol;
char * outbuf = NULL;
......@@ -494,7 +506,7 @@ static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, bool ha
prefix_copy = paragraph->prefix.bytes + strlen(paragraph->prefix.bytes) - (outlen / 2);
while (*prefix_copy != ' ')
prefix_copy--;
word_len = get_word_len(prefix_copy, -1, is_utf8);
word_len = get_word_len(prefix_copy, -1, is_utf8, pipe_codes);
prefix_cols = word_len.len;
prefix_bytes = word_len.bytes;
}
......@@ -525,10 +537,10 @@ static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, bool ha
if (*inp == 0)
break;
ws_len = get_ws_len(inp, outcol);
word_len = get_word_len(inp + ws_len.bytes, -1, is_utf8);
word_len = get_word_len(inp + ws_len.bytes, -1, is_utf8, pipe_codes);
// Do we need to chop a long word?
if (word_len.len > (outlen - prefix_cols))
word_len = get_word_len(inp + ws_len.bytes, outlen - ws_len.bytes - outcol, is_utf8);
word_len = get_word_len(inp + ws_len.bytes, outlen - ws_len.bytes - outcol, is_utf8, pipe_codes);
if (outcol + ws_len.len + word_len.len > outlen) {
inp += ws_len.bytes;
break;
......@@ -551,7 +563,7 @@ static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, bool ha
return outbuf;
}
char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf8)
char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf8, bool pipe_codes)
{
char* outbuf;
struct paragraph *paragraphs;
......@@ -559,7 +571,7 @@ char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf
if (oldlen < 1)
oldlen = 79;
paragraphs = word_unwrap(inbuf, oldlen, handle_quotes, &has_crs, is_utf8);
paragraphs = word_unwrap(inbuf, oldlen, handle_quotes, &has_crs, is_utf8, pipe_codes);
if (paragraphs == NULL)
return NULL;
#if 0
......@@ -567,7 +579,7 @@ char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf
fprintf(stderr, "PREFIX: '%s'\nTEXT: '%s'\n\n", paragraphs[i].prefix.bytes, paragraphs[i].text);
#endif
outbuf = wrap_paragraphs(paragraphs, len, handle_quotes, has_crs, is_utf8);
outbuf = wrap_paragraphs(paragraphs, len, handle_quotes, has_crs, is_utf8, pipe_codes);
free_paragraphs(paragraphs, -1);
free(paragraphs);
return outbuf;
......
......@@ -24,7 +24,7 @@
extern "C" {
#endif
char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf8);
char* wordwrap(char* inbuf, int len, int oldlen, bool handle_quotes, bool is_utf8, bool pipe_codes);
#ifdef __cplusplus
}
......
......@@ -125,7 +125,7 @@ bool sbbs_t::quotemsg(smb_t* smb, smbmsg_t* msg, bool tails)
wrap_cols = cfg.xedit[useron_xedit - 1]->quotewrap_cols;
if (wrap_cols == 0)
wrap_cols = cols - 1;
wrapped = ::wordwrap(buf, wrap_cols, org_cols - 1, /* handle_quotes: */ TRUE, is_utf8);
wrapped = ::wordwrap(buf, wrap_cols, org_cols - 1, /* handle_quotes: */ TRUE, is_utf8, /* pipe_codes: */false);
}
if (wrapped != NULL) {
fputs(wrapped, fp);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment