Author Topic: format_desc()  (Read 690 times)

Offline quixadhal

  • BFF
  • ***
  • Posts: 474
    • View Profile
    • Shadowlord.org
format_desc()
« on: August 20, 2012, 02:25:50 AM »
Here's a little function I threw together to make description formatting a standard API.  Various muds do room descriptions in different ways, some like to indent the first line and leave the rest on the left edge, others do the opposite, and some indent the whole thing.

Here's a bit of code to make that simpler.  Improvements welcome!

Code: [Select]

string format_desc(int terminal_width, int leading_indent_width, int inner_indent_width, string raw) {
    string result = "";

    string *paragraphs = rexplode(raw, "\n");
    string leading_indent = sprintf("%-*.*s", leading_indent_width, leading_indent_width, " ");
    string inner_indent = sprintf("%-*.*s", inner_indent_width, inner_indent_width, " ");

    for(int i = 0; i < sizeof(paragraphs); i++) {
        string p = paragraphs[i];

        result += (i != 0 ? "" : "");
        result += leading_indent + implode(explode(sprintf("%-=*s\n", terminal_width, p), "\n"), "\n" + inner_indent);
        result += "\n";
    }
    return result;
}

Note that terminal width is the width you want the wrap to occur at, including the largest indent you provide, which should be less than your actual terminal width.  I tend to use 75 with an indent of 4.

Offline quixadhal

  • BFF
  • ***
  • Posts: 474
    • View Profile
    • Shadowlord.org
Re: format_desc()
« Reply #1 on: August 20, 2012, 03:10:56 AM »
Hmmm, can't edit, so here's a newer version that's a bit more flexible and has some error checking.  Interestingly, sprintf("%0.0s", " "), will still generate a one character string, even though the width limit is 0.  I call that a bug in sprintf.

Code: [Select]
varargs string format_desc(string raw, int terminal_width, int leading_indent_width, int inner_indent_width, string *highlight, string highlight_color) {
    string result = "";

    string *paragraphs = rexplode(raw, "\n");
    string leading_indent = "";
    string inner_indent = "";


    if(undefinedp(terminal_width) || terminal_width < 10) {
        object tp = this_player();

        terminal_width = 75;
        if(!undefinedp(tp)) {
            int sw = tp->GetScreen()[0];

            if(!undefinedp(sw) && sw > 0) {
                terminal_width = sw;
            }
        }
    }

    if(!undefinedp(leading_indent_width) && leading_indent_width > 0) {
        leading_indent = sprintf("%-*.*s", leading_indent_width, leading_indent_width, " ");
    }
    if(!undefinedp(inner_indent_width) && inner_indent_width > 0) {
        inner_indent = sprintf("%-*.*s", inner_indent_width, inner_indent_width, " ");
    }

    for(int i = 0; i < sizeof(paragraphs); i++) {
        string p = paragraphs[i];

        result += (i != 0 ? "" : "");
        result += leading_indent + implode(explode(sprintf("%-=*s\n", terminal_width, p), "\n"), "\n" + inner_indent);
        result += "\n";
    }

    if(!undefinedp(highlight)) {
        if(undefinedp(highlight_color)) {
            highlight_color = "%^BOLD%^%^YELLOW%^";
        }
        foreach(string h in highlight) {
            result = replace_string(result, h, highlight_color + h + "%^RESET%^", 1);
        }
    }

    return result;
}

Offline quixadhal

  • BFF
  • ***
  • Posts: 474
    • View Profile
    • Shadowlord.org
Re: format_desc()
« Reply #2 on: August 20, 2012, 03:12:45 AM »
Oh yeah, since this is now long enough to be confusing... here's an example usage:

Code: [Select]
static void create() {
    int width = 90;
    int leading = 4;
    int inner = 0;
...

    SetShort("Common Room");
    SetLong(format_desc(
            "The common room of the Griffin's Tale is a quiet place.\n"
            "A long table fills the center of this warm and comfortable "
            "room.  A bright and servicable bar occupies the east and "
            "south walls, almost entirely. A warm fireplace fills the "
            "north wall.\n"
            "A solid, if somewhat beaten, oak door leads out into the "
            "street to the west.  An open archway leads past the fireplace "
            "and into the kitchen northwards.  To the east, a set of double "
            "doors leads deeper into the inn.  Along the south wall, sits "
            "a smaller door.",
            width, leading, inner,
            ({ "long table", "bar", "fireplace", "oak door", "archway", "double doors", "smaller door" })
            ));
    SetItems( ([
                ({ "long table", "table" }) : format_desc(
                        "A long table, with many battle scars, attests to times that "
                        "were not so quiet.  Several large candelobras perch on the "
                        "tabletop, and provide much of the light here.  A few oil lamps "
                        "hang from the rafters, but do little but brighten the smoke-filled "
                        "air.  The bench seat along one side is noticably shorter than "
                        "the bench on the other side.  A few smaller round tables lurk "
                        "around the less well-lit edges of the room.",
                        width, leading, inner
                        ),
...

And it looks like:



Also, WOOT!  Post 333, halfway to the posting of the beast!
« Last Edit: August 20, 2012, 03:17:36 AM by quixadhal »

Offline quixadhal

  • BFF
  • ***
  • Posts: 474
    • View Profile
    • Shadowlord.org
Re: format_desc()
« Reply #3 on: August 20, 2012, 03:55:34 AM »
Fixed a bug where a multi-word highlight keyword (such as "oil lamp") crossed a line wrap boundry, and was thus missed.  All this would be unnecessary if sprintf() understood pinkfish codes:

Code: [Select]

varargs string format_desc(string raw, int terminal_width, int leading_indent_width, int inner_indent_width, string *highlight, string highlight_color) {
    string result = "";

    string *paragraphs = rexplode(raw, "\n");
    string leading_indent = "";
    string inner_indent = "";


    if(undefinedp(terminal_width) || terminal_width < 10) {
        object tp = this_player();

        terminal_width = 75;
        if(!undefinedp(tp)) {
            int sw = tp->GetScreen()[0];

            if(!undefinedp(sw) && sw > 0) {
                terminal_width = sw;
            }
        }
    }

    if(!undefinedp(leading_indent_width) && leading_indent_width > 0) {
        leading_indent = sprintf("%-*.*s", leading_indent_width, leading_indent_width, " ");
    }
    if(!undefinedp(inner_indent_width) && inner_indent_width > 0) {
        inner_indent = sprintf("%-*.*s", inner_indent_width, inner_indent_width, " ");
    }

    for(int i = 0; i < sizeof(paragraphs); i++) {
        string p = paragraphs[i];

        result += (i != 0 ? "" : "");
        result += leading_indent + implode(explode(sprintf("%-=*s\n", terminal_width, p), "\n"), "\n" + inner_indent);
        result += "\n";
    }

    if(!undefinedp(highlight)) {
        if(undefinedp(highlight_color)) {
            highlight_color = "%^BOLD%^%^YELLOW%^";
        }

        foreach(string h in highlight) {
            result = replace_string(result, h, highlight_color + h + "%^RESET%^", 1);
            if(strsrch(h, " ") != -1) {
                string *words = explode(h, " ");

                for(int i = 0; i < sizeof(words); i++) {
                    string t = replace_string(h, " ", "\n", i+1, i+1);
                    result = replace_string(result, t, highlight_color + t + "%^RESET%^", 1);
                }
            }
        }
    }

    return result;
}