Advertisement
NovaYoshi

ConvertBBCode

Sep 7th, 2014
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.02 KB | None | 0 0
  1. const char __attribute__ ((hot)) *ConvertBBCode(char *Output, const char *Input, int BufSize) {
  2.   if(!strchr(Input, '[')) return Input; // no conversion necessary
  3.  
  4.   const char *TagName[] = {"b]","i]","u]","s]","sub]","sup]","url=","url]","icon]","user]","color=","color]","noparse]",NULL};
  5.   const int TagLen[] = {2, 2, 2, 2, 4, 4, 4, 4, 5, 5, 6, 6, 8}; // 5+ treated specially
  6.   const char *TagEndName[] = {"[/b]","[/i]","[/u]","[/s]","[/sub]","[/sup]","[/url]","[/url]","[/icon]","[/user]","[/color]",NULL,"[/noparse]"};
  7.   const int TagCodes[] = {0x02, 0x1d, 0x1f, 128+FORMAT_STRIKEOUT, 128+FORMAT_SUBSCRIPT, 128+FORMAT_SUPERSCRIPT,
  8.     128+FORMAT_URL_LINK, 128+FORMAT_URL_LINK, 128+FORMAT_ICON_CMDLINK, 128+FORMAT_COMMAND_LINK,
  9.     128+FORMAT_CANCEL_COLORS, 128+FORMAT_CANCEL_COLORS};
  10.   int TagEnabled[] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
  11.   char *Out = Output;
  12.   int i; // tag index to try
  13.  
  14.   while(*Input) {
  15.     char c = *(Input++);
  16.     if(c != '[') // if not [ just copy it
  17.       *(Out++) = c;
  18.     else
  19.       if(*Input == '/') { // cancel formatting
  20.         for(i=0;TagName[i];i++)
  21.           if(!memcmp(Input+1, TagName[i], TagLen[i])) {
  22.             if(TagEnabled[i]) {
  23.               Input+=TagLen[i]+1;
  24.               if(TagCodes[i] & 128) // need escape code?
  25.                 *(Out++) = 0xff;
  26.               *(Out++) = TagCodes[i]&127;
  27.               TagEnabled[i] = 0;
  28.             } else {
  29.               *(Out++) = '['; // tag isn't enabled, print it
  30.             }
  31.             break;
  32.           }
  33.         if(!TagName[i]) // put the [ if not a valid tag
  34.           *(Out++) = '[';
  35.       } else { // start formatting
  36.         for(i=0;TagName[i];i++)
  37.           if(!memcmp(Input, TagName[i], TagLen[i])) {
  38.             if(!TagEndName[i] || !strstr(Input, TagEndName[i])) { // if tag isn't closed, tag should be visible
  39.               *(Out++) = '['; // add the [ back
  40.               break;
  41.             }
  42.             Input+=TagLen[i];
  43.             if(TagLen[i] < 6) { // 6+ handle outputting on their own
  44.               if(TagCodes[i] & 128) // need escape code?
  45.                 *(Out++) = 0xff;
  46.               *(Out++) = TagCodes[i]&127;
  47.               if(i!=6)
  48.                 TagEnabled[i] = 1;
  49.               else // url= has to set url]
  50.                 TagEnabled[i+1] = 1;
  51.             }
  52.             // special handling for lengths of at least 5
  53.             if(TagLen[i]>=5) {
  54.               if(TagLen[i]==5) { // [icon] or [user], stick in a command name
  55.                 strcpy(Out, "char ");
  56.                 Out+=5;
  57.               } else if(TagLen[i]==6) { // [color]
  58.                 const char *End = strchr(Input, ']');
  59.                 char ColorName[End-Input+1];
  60.                 strlcpy(ColorName, Input, sizeof(ColorName));
  61.                 Input = End+1;
  62.                 if(*ColorName == '#') { // hex color
  63.                   *(Out++) = 0x04;
  64.                   if(strlen(ColorName) == 4) { // convert 3 digit to 6 digit
  65.                     for(int j=1;j<4;j++) { // double every digit
  66.                       *(Out++)=ColorName[j];
  67.                       *(Out++)=ColorName[j];
  68.                     }
  69.                   } else { // assume 6 digits
  70.                     strcpy(Out, ColorName+1);
  71.                     Out+=6;
  72.                   }
  73.                 } else {
  74.                   for(int j=0;FChatColorNames[j];j++)
  75.                     if(!strcasecmp(ColorName, FChatColorNames[j])) {
  76.                       sprintf(ColorName, "\3%.2d", j+16); // F-Chat colors start at 16
  77.                       strcpy(Out, ColorName);
  78.                       Out+=3;
  79.                       break;
  80.                     }
  81.                 }
  82.                 TagEnabled[i+1] = 1;
  83.               } else { // [noparse]
  84.                 const char *End = strstr(Input, "[/noparse]");
  85.                 memcpy(Out, Input, End-Input);
  86.                 Out+=(End-Input)+10;
  87.               }
  88.             }
  89.             break;
  90.           }
  91.         if(!TagName[i]) // put the [ if not a valid tag
  92.           *(Out++) = '[';
  93.       }
  94.   }
  95.   *Out = 0;
  96.   return Output;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement