...
 
Commits (1)
  • Rob Swindell's avatar
    Support markup tags (optionally) when displaying posts · adb896c1
    Rob Swindell authored
    Defaults to "Off" ("No") and can be set per-sub-board to either:
    - "Yes" parse/apply markup style to displayed message text while still displaying the markup tags
    - "Hide" parse/apply markup style to displayed message text and hide (don't display) the markup tags
    - "No", treat marked-up messages the same as any other message text, same as before.
    
    The supported Markup tags at this time are:
    #bold text#
    /Italicized text/
    _underlined text_
    #inverse text#
    
    Now, ANSI-BBS terminals (and Synchronet) do not support the concept of italic or underlined text (at least, not yet) - so those styles become combinations of the blink and high-intensity attributes which can be used to choose alternate fonts and this works well.
    
    These 4 styles were chosen to be compatible with GoldEd's "Style Codes", though GoldEd is actually very configurable in its support of these tags/codes and its possible we're not 100% compatible. For example, GoldEd (and SemPoint) both support the combining of tags/codes to created combinations of styled text - Synchronet does not (this is consistent with Mozilla/Thunderbird's "Structured Text").
    
    Multiple words can be styled with a single set of tags, but the first and last word must be delimited by white-space (this is not consistent with Markdown).
    
    Multiple lines can be styled with a single set of tags, but not multiple paragraphs (this is consistent with Markdown).
    
    The rules I chose were to minimize false positives but maintain some interoperability with GoldEd and Thunderbird with a familiar/common tag syntax.
    adb896c1
......@@ -89,6 +89,7 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
char tmp2[256],tmp3[128];
char* str=(char*)buf;
uchar exatr=0;
char mark = '\0';
int i;
ulong l=0;
uint lines_printed = 0;
......@@ -158,6 +159,43 @@ char sbbs_t::putmsgfrag(const char* buf, long* mode, long org_cols, JSObject* ob
}
break;
}
if((*mode) & P_MARKUP) {
if(((mark == 0) && (str[l] == '*' || str[l] == '/' || str[l] == '_' || str[l] == '#')) || str[l] == mark) {
char* next= NULL;
if(mark == 0)
next = strchr(str + l + 1, str[l]);
char *blank = strstr(str + l + 1, "\n\r");
if(((l < 1 || isspace(str[l - 1]))
&& isalnum(str[l + 1]) && mark == 0 && next != NULL && (*(next + 1) == '\0' || isspace(*(next + 1))) && (blank == NULL || next < blank))
|| (l > 0 && (isalnum(str[l - 1]) || ispunct(str[l - 1])) && str[l] == mark)) {
if(mark == 0)
mark = str[l];
else {
mark = 0;
if(!((*mode) & P_HIDEMARKS))
outchar(str[l]);
}
switch(str[l]) {
case '*':
attr(curatr ^ HIGH);
break;
case '/':
attr(curatr ^ BLINK);
break;
case '_':
attr(curatr ^ (HIGH|BLINK));
break;
case '#':
attr(((curatr&0x0f) << 4) | ((curatr&0xf0) >> 4));
break;
}
if(mark != 0 && !((*mode) & P_HIDEMARKS))
outchar(str[l]);
l++;
continue;
}
}
}
if(str[l]==CTRL_A && str[l+1]!=0) {
if(str[l+1]=='"' && !(sys_status&SS_NEST_PF) && !((*mode)&P_NOATCODES)) { /* Quote a file */
l+=2;
......
......@@ -787,6 +787,8 @@ typedef enum { /* Values for xtrn_t.event */
#define P_UTF8 (1<<13) /* Message is UTF-8 */
#define P_AUTO_UTF8 (1<<14) /* Message may be UTF-8, auto-detect */
#define P_NOXATTRS (1<<15) /* No "Extra Attribute Codes" supported */
#define P_MARKUP (1<<16) /* Support StyleCodes/Rich/StructuredText */
#define P_HIDEMARKS (1<<17) /* Hide the mark-up characters */
/* Bits in 'mode' for listfiles */
#define FL_ULTIME (1<<0) /* List files by upload time */
......
......@@ -560,6 +560,8 @@ void sub_cfg(uint grpnum)
#endif
sprintf(opt[n++],"%-27.27s%s","Compress Messages (LZH)"
,cfg.sub[i]->misc&SUB_LZH ? "Yes" : "No");
sprintf(opt[n++],"%-27.27s%s","Apply Markup Codes"
,cfg.sub[i]->pmode&P_MARKUP ? ((cfg.sub[i]->pmode&P_HIDEMARKS) ? "Hide" : "Yes") : "No");
sprintf(opt[n++],"%-27.27s%s","Extra Attribute Codes"
,cfg.sub[i]->pmode&P_NOXATTRS ? "No" : "Yes");
sprintf(opt[n++],"%-27.27s%s","Word-wrap Messages"
......@@ -581,7 +583,7 @@ void sub_cfg(uint grpnum)
if(n==-1)
break;
switch(n) {
case 0:
case __COUNTER__:
if(cfg.sub[i]->misc&SUB_PONLY)
n=2;
else
......@@ -620,7 +622,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc|=(SUB_PRIV|SUB_PONLY);
}
break;
case 1:
case __COUNTER__:
if(cfg.sub[i]->misc&SUB_AONLY)
n=2;
else
......@@ -659,7 +661,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc|=(SUB_ANON|SUB_AONLY);
}
break;
case 2:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_NAME) ? 0:1;
uifc.helpbuf=
"`User Real Names in Posts on Sub-board:`\n"
......@@ -682,7 +684,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_NAME;
}
break;
case 3:
case __COUNTER__:
if(cfg.sub[i]->misc&SUB_EDITLAST)
n=2;
else
......@@ -727,7 +729,7 @@ void sub_cfg(uint grpnum)
break;
}
break;
case 4:
case __COUNTER__:
if(cfg.sub[i]->misc&SUB_DELLAST)
n=2;
else
......@@ -768,7 +770,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc|=(SUB_DEL|SUB_DELLAST);
}
break;
case 5:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_NSDEF) ? 0:1;
uifc.helpbuf=
"`Default On for New Scan:`\n"
......@@ -790,7 +792,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_NSDEF;
}
break;
case 6:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_FORCED) ? 0:1;
uifc.helpbuf=
"`Forced On for New Scan:`\n"
......@@ -813,7 +815,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_FORCED;
}
break;
case 7:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_SSDEF) ? 0:1;
uifc.helpbuf=
"`Default On for Your Scan:`\n"
......@@ -835,7 +837,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_SSDEF;
}
break;
case 8:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_TOUSER) ? 0:1;
uifc.helpbuf=
"`Prompt for 'To' User on Public Posts:`\n"
......@@ -858,7 +860,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_TOUSER;
}
break;
case 9:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_NOVOTING) ? 1:0;
uifc.helpbuf=
"`Allow Message Voting:`\n"
......@@ -880,7 +882,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc ^= SUB_NOVOTING;
}
break;
case 10:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_QUOTE) ? 0:1;
uifc.helpbuf=
"`Allow Message Quoting:`\n"
......@@ -902,7 +904,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_QUOTE;
}
break;
case 11:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_MSGTAGS) ? 0:1;
uifc.helpbuf=
"`Allow Message Tagging:`\n"
......@@ -924,7 +926,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_MSGTAGS;
}
break;
case 12:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_NOUSERSIG) ? 0:1;
uifc.helpbuf=
"Suppress User Signatures:\n"
......@@ -946,7 +948,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_NOUSERSIG;
}
break;
case 13:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_SYSPERM) ? 0:1;
uifc.helpbuf=
"`Operator Messages Automatically Permanent:`\n"
......@@ -1008,7 +1010,7 @@ void sub_cfg(uint grpnum)
}
break;
#endif
case 14:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_LZH) ? 0:1;
uifc.helpbuf=
"`Compress Messages with LZH Encoding:`\n"
......@@ -1037,7 +1039,44 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->misc&=~SUB_LZH;
}
break;
case 15:
case __COUNTER__:
n = (cfg.sub[i]->pmode&P_MARKUP) ? (cfg.sub[i]->pmode&P_HIDEMARKS ? 1 : 0) : 2;
uifc.helpbuf=
"`Interpret/Display Markup Codes in Messages:`\n"
"\n"
"Markup codes are called 'StyleCodes' in GoldEd, 'Rich Text' in SemPoint,\n"
"and 'Structured Text' in Mozilla/Thunderbird.\n"
"\n"
"`*Bold Text*`\n"
"/Italic Text/\n"
"~#Inverse Text#~\n"
"_Underlined Text_\n"
"\n"
"Markup character cannot be combined.\n"
;
strcpy(opt[0],"Yes");
strcpy(opt[1],"Yes and Hide the Markup Characters");
strcpy(opt[2],"No");
opt[3][0]=0;
n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
,"Interpret/Display Markup Codes in Messages", opt);
if(n==-1)
break;
if(n == 0 && (cfg.sub[i]->pmode&(P_MARKUP|P_HIDEMARKS)) != P_MARKUP) {
uifc.changes = TRUE;
cfg.sub[i]->pmode |= P_MARKUP;
cfg.sub[i]->pmode &= ~P_HIDEMARKS;
}
else if(n == 1 && (cfg.sub[i]->pmode&(P_MARKUP|P_HIDEMARKS)) != (P_MARKUP|P_HIDEMARKS)) {
uifc.changes = TRUE;
cfg.sub[i]->pmode |= (P_MARKUP|P_HIDEMARKS);
}
else if(n == 2 && (cfg.sub[i]->pmode&(P_MARKUP|P_HIDEMARKS)) != 0) {
uifc.changes = TRUE;
cfg.sub[i]->pmode &= ~(P_MARKUP|P_HIDEMARKS);
}
break;
case __COUNTER__:
n=(cfg.sub[i]->pmode&P_NOXATTRS) ? 1:0;
uifc.helpbuf=
"`Extra Attribute Codes:`\n"
......@@ -1059,7 +1098,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->pmode ^= P_NOXATTRS;
}
break;
case 16:
case __COUNTER__:
n=(cfg.sub[i]->n_pmode&P_WORDWRAP) ? 1:0;
uifc.helpbuf=
"`Word-wrap Message Text:`\n"
......@@ -1081,7 +1120,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->n_pmode ^= P_WORDWRAP;
}
break;
case 17:
case __COUNTER__:
n=(cfg.sub[i]->pmode&P_AUTO_UTF8) ? 0:1;
uifc.helpbuf=
"`Automatically Detect UTF-8 Message Text:`\n"
......@@ -1105,7 +1144,7 @@ void sub_cfg(uint grpnum)
cfg.sub[i]->pmode ^= P_AUTO_UTF8;
}
break;
case 18:
case __COUNTER__:
n=(cfg.sub[i]->misc&SUB_TEMPLATE) ? 0:1;
uifc.helpbuf=
"`Use this Sub-board as a Template for New Subs:`\n"
......