From 284346fa213dcfac6d5b0c3ae0e283626d66eb6a Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sat, 4 Mar 2006 02:37:41 +0000 Subject: [PATCH] Add quoting sensitivity to word_wrap() re-wraps quoted text to still fit. Currently, the options are [width [, orig_width [, [quotes]]] That should be updated to allow the boolean to be pretty much anywhere fitting with the rest of the JS stuff... but I'm too lazy. Also, this should (probobly) be moved somewhere else so that the internal editor could make use of it too. Further, should this optionally support ANSI, pipe-codes, and WWIV colour codes? --- src/sbbs3/js_global.c | 133 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 13 deletions(-) diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c index 6fd4e80e92..405c41d013 100644 --- a/src/sbbs3/js_global.c +++ b/src/sbbs3/js_global.c @@ -614,12 +614,16 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) int32 l,len=79; int32 oldlen=79; int32 crcount; + JSBool handle_quotes=JS_TRUE; ulong i,k,t; int ocol=1; int icol=1; uchar* inbuf; char* outbuf; char* linebuf; + char* prefix=NULL; + int prefix_len=0; + int prefix_bytes=0; JSString* js_str; if(JSVAL_IS_VOID(argv[0])) @@ -637,9 +641,17 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if(argc>2) JS_ValueToInt32(cx,argv[2],&oldlen); + if(argc>3 && JSVAL_IS_BOOLEAN(argv[3])) + handle_quotes=JSVAL_TO_BOOLEAN(argv[3]); + if((linebuf=(char*)malloc((len*2)+2))==NULL) /* room for ^A codes */ return(JS_FALSE); + if(handle_quotes) { + if((prefix=(char *)malloc((len*2)+2))==NULL) /* room for ^A codes */ + return(JS_FALSE); + } + outbuf[0]=0; for(i=l=0; inbuf[i]; i++) { switch(inbuf[i]) { @@ -654,12 +666,97 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) l=0; ocol=1; } - else if(isspace(inbuf[i+1])) { /* Next line starts with whitespace. This is a "hard" CR. */ - linebuf[l++]='\r'; - linebuf[l++]='\n'; - strncat(outbuf, linebuf, l); - l=0; - ocol=1; + else if(isspace(inbuf[i+1])) { /* Next line starts with whitespace. This is a "hard" CR. or quoted */ + if(handle_quotes) { + /* k will be the new prefix_bytes */ + t=1; + k=prefix_bytes; + prefix_bytes=0; + prefix_len=0; + while(t && t<6) { + prefix_bytes++; + /* Skip CTRL-A codes */ + while(inbuf[i+prefix_bytes]=='\x01') { + k++; + if(inbuf[i+prefix_bytes]=='\x01') + break; + k++; + } + prefix_len++; + switch(t) { + case 1: /* At start of possible quote (Next char should be space) */ + if(inbuf[i+prefix_bytes]!=' ') { + if(prefix_bytes>1) + t=6; + } + else + t++; + break; + case 2: /* At start of nick (next char should be alphanum or '>') */ + if(inbuf[i+prefix_bytes]==' ') + t=0; + else { + if(inbuf[i+prefix_bytes]=='>') + t=5; + else + t++; + } + break; + case 3: /* At second nick initial (next char should be alphanum or '>') */ + if(inbuf[i+prefix_bytes]==' ') + t=0; + else { + if(inbuf[i+prefix_bytes]=='>') + t=5; + else + t++; + } + break; + case 4: /* After two regular chars, next should HAS to be a '>') */ + if(inbuf[i+prefix_bytes]!='>') + t=0; + else + t++; + break; + case 5: /* At '>' next char must be a space */ + if(inbuf[i+prefix_bytes]!=' ') + t=0; + else + t++; + break; + } + } + if(!t) { + prefix_bytes=0; + prefix_len=0; + prefix[0]=0; + } + else { + /* New prefix (different len, or different text)? Force a new line and copy the new prefix */ + if(prefix_bytes != k || (!memcmp(prefix,inbuf+i+1,prefix_bytes+1))) { + memcpy(prefix,inbuf+i+1,prefix_bytes); + prefix[prefix_bytes]=0; + linebuf[l++]='\r'; + linebuf[l++]='\n'; + strncat(outbuf, linebuf, l); + if(prefix) + strcpy(linebuf,prefix); + l=prefix_bytes; + ocol=prefix_len; + i++; /* Do not keep the space (ie: cheat) for the first line of this quote block */ + } + i+=prefix_bytes-1; /* Keep the space (kinda a cheat... don't tell anyone) */ + } + } + else { + linebuf[l++]='\r'; + linebuf[l++]='\n'; + strncat(outbuf, linebuf, l); + if(prefix) + strcpy(linebuf,prefix); + l=prefix_bytes; + ocol=prefix_len; + } } else { if(icol < oldlen) { /* If this line is overly long, It's impossible for the next word to fit */ @@ -669,8 +766,10 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) linebuf[l++]='\r'; linebuf[l++]='\n'; strncat(outbuf, linebuf, l); - l=0; - ocol=1; + if(prefix) + strcpy(linebuf,prefix); + l=prefix_bytes; + ocol=prefix_len; } else { /* Not a hard CR... add space if needed */ if(!isspace(linebuf[l-1])) @@ -743,11 +842,15 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) strncat(outbuf, linebuf, l+1); strcat(outbuf, "\r\n"); /* Move trailing words to start of buffer. */ + l=prefix_bytes; if(k-t>0) /* k-1 is the last char position. t is the start of the next line position */ - memmove(linebuf, linebuf+t, k-t); - l=k-t; + memmove(linebuf+l, linebuf+t, k-t); + if(prefix) + memcpy(linebuf,prefix,prefix_bytes); + ocol=prefix_len; + l+=k-t; /* Find new ocol */ - for(ocol=1,t=0; t<l; t++) { + for(ocol=prefix_len+1,t=0; t<l; t++) { switch(linebuf[t]) { case '\x01': /* CTRL-A */ if(linebuf[t+1]!='\x01') @@ -777,6 +880,8 @@ js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) js_str = JS_NewStringCopyZ(cx, outbuf); free(outbuf); + if(prefix) + free(prefix); if(js_str==NULL) return(JS_FALSE); @@ -2887,8 +2992,10 @@ static jsSyncMethodSpec js_global_functions[] = { ,JSDOCSTR("return a decoded HTML-encoded text string") ,311 }, - {"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt>]") - ,JSDOCSTR("returns a word-wrapped version of the text string argument, <i>line_length</i> defaults to <i>79</i>") + {"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt>]]]]") + ,JSDOCSTR("returns a word-wrapped version of the text string argument optionally handing quotes magically, " + "<i>line_length</i> defaults to <i>79</i> <i>orig_line_length</i> defaults to <i>79</i> " + "and <i>handle_quotes</i> defaults to <i>true</i>") ,311 }, {"quote_msg", js_quote_msg, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt>] [,prefix=<tt>\" > \"</tt>]") -- GitLab