skylib_fluffos_v3/
skylib_fluffos_v3/bin/
skylib_fluffos_v3/bin/db/
skylib_fluffos_v3/fluffos-2.9-ds2.04/
skylib_fluffos_v3/fluffos-2.9-ds2.04/ChangeLog.old/
skylib_fluffos_v3/fluffos-2.9-ds2.04/Win32/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/
skylib_fluffos_v3/fluffos-2.9-ds2.04/compat/simuls/
skylib_fluffos_v3/fluffos-2.9-ds2.04/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/clone/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/command/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/data/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/etc/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/include/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/inherit/master/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/log/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/compiler/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/efuns/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/single/tests/operators/
skylib_fluffos_v3/fluffos-2.9-ds2.04/testsuite/u/
skylib_fluffos_v3/fluffos-2.9-ds2.04/tmp/
skylib_fluffos_v3/fluffos-2.9-ds2.04/windows/
skylib_fluffos_v3/mudlib/
skylib_fluffos_v3/mudlib/cmds/
skylib_fluffos_v3/mudlib/cmds/admin/
skylib_fluffos_v3/mudlib/cmds/guild-race/
skylib_fluffos_v3/mudlib/cmds/living/broken/
skylib_fluffos_v3/mudlib/cmds/player/group_cmds/
skylib_fluffos_v3/mudlib/cmds/playtester/
skylib_fluffos_v3/mudlib/d/admin/
skylib_fluffos_v3/mudlib/d/admin/room/
skylib_fluffos_v3/mudlib/d/admin/room/we_care/
skylib_fluffos_v3/mudlib/d/admin/save/
skylib_fluffos_v3/mudlib/d/admin/text/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/buildings/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/map/
skylib_fluffos_v3/mudlib/d/learning/TinyTown/roads/
skylib_fluffos_v3/mudlib/d/learning/chars/
skylib_fluffos_v3/mudlib/d/learning/functions/
skylib_fluffos_v3/mudlib/d/learning/handlers/
skylib_fluffos_v3/mudlib/d/learning/help_topics/
skylib_fluffos_v3/mudlib/d/learning/help_topics/npcs/
skylib_fluffos_v3/mudlib/d/learning/help_topics/objects/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rcs_demo/RCS/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/crowd/
skylib_fluffos_v3/mudlib/d/learning/help_topics/rooms/situations/
skylib_fluffos_v3/mudlib/d/learning/save/
skylib_fluffos_v3/mudlib/d/learning/school/
skylib_fluffos_v3/mudlib/d/learning/school/add_sc/
skylib_fluffos_v3/mudlib/d/learning/school/characters/
skylib_fluffos_v3/mudlib/d/learning/school/general/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/basic_commands/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/edtutor/
skylib_fluffos_v3/mudlib/d/learning/school/getting-started/unix_tutor/
skylib_fluffos_v3/mudlib/d/learning/school/items/
skylib_fluffos_v3/mudlib/d/learning/school/npc_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/room_basic/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/situations/
skylib_fluffos_v3/mudlib/d/learning/school/room_school/terrain_tutor/
skylib_fluffos_v3/mudlib/d/learning/text/
skylib_fluffos_v3/mudlib/d/liaison/
skylib_fluffos_v3/mudlib/d/mudlib/
skylib_fluffos_v3/mudlib/d/mudlib/changes/
skylib_fluffos_v3/mudlib/d/playtesters/
skylib_fluffos_v3/mudlib/d/playtesters/effects/
skylib_fluffos_v3/mudlib/d/playtesters/handlers/
skylib_fluffos_v3/mudlib/d/playtesters/items/
skylib_fluffos_v3/mudlib/d/sage/
skylib_fluffos_v3/mudlib/doc/
skylib_fluffos_v3/mudlib/doc/creator/
skylib_fluffos_v3/mudlib/doc/driver/
skylib_fluffos_v3/mudlib/doc/driver/efuns/arrays/
skylib_fluffos_v3/mudlib/doc/driver/efuns/buffers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/calls/
skylib_fluffos_v3/mudlib/doc/driver/efuns/compile/
skylib_fluffos_v3/mudlib/doc/driver/efuns/filesystem/
skylib_fluffos_v3/mudlib/doc/driver/efuns/floats/
skylib_fluffos_v3/mudlib/doc/driver/efuns/functions/
skylib_fluffos_v3/mudlib/doc/driver/efuns/general/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mappings/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mixed/
skylib_fluffos_v3/mudlib/doc/driver/efuns/mudlib/
skylib_fluffos_v3/mudlib/doc/driver/efuns/numbers/
skylib_fluffos_v3/mudlib/doc/driver/efuns/parsing/
skylib_fluffos_v3/mudlib/doc/login/
skylib_fluffos_v3/mudlib/doc/lpc/basic_manual/
skylib_fluffos_v3/mudlib/doc/lpc/intermediate/
skylib_fluffos_v3/mudlib/doc/new/add_command/
skylib_fluffos_v3/mudlib/doc/new/events/
skylib_fluffos_v3/mudlib/doc/new/handlers/
skylib_fluffos_v3/mudlib/doc/new/living/race/
skylib_fluffos_v3/mudlib/doc/new/living/spells/
skylib_fluffos_v3/mudlib/doc/new/object/
skylib_fluffos_v3/mudlib/doc/new/player/
skylib_fluffos_v3/mudlib/doc/new/room/guild/
skylib_fluffos_v3/mudlib/doc/new/room/outside/
skylib_fluffos_v3/mudlib/doc/new/room/storeroom/
skylib_fluffos_v3/mudlib/doc/object/
skylib_fluffos_v3/mudlib/doc/playtesters/
skylib_fluffos_v3/mudlib/doc/policy/
skylib_fluffos_v3/mudlib/doc/weapons/
skylib_fluffos_v3/mudlib/global/
skylib_fluffos_v3/mudlib/global/creator/
skylib_fluffos_v3/mudlib/handlers/
skylib_fluffos_v3/mudlib/include/casino/
skylib_fluffos_v3/mudlib/include/cmds/
skylib_fluffos_v3/mudlib/include/effects/
skylib_fluffos_v3/mudlib/include/npc/
skylib_fluffos_v3/mudlib/include/room/
skylib_fluffos_v3/mudlib/include/shops/
skylib_fluffos_v3/mudlib/net/daemon/
skylib_fluffos_v3/mudlib/net/daemon/chars/
skylib_fluffos_v3/mudlib/net/inherit/
skylib_fluffos_v3/mudlib/net/obj/
skylib_fluffos_v3/mudlib/net/obj/BACKUPS/
skylib_fluffos_v3/mudlib/obj/amulets/
skylib_fluffos_v3/mudlib/obj/armours/plate/
skylib_fluffos_v3/mudlib/obj/b_day/
skylib_fluffos_v3/mudlib/obj/clothes/transport/horse/
skylib_fluffos_v3/mudlib/obj/faith/symbols/
skylib_fluffos_v3/mudlib/obj/fungi/
skylib_fluffos_v3/mudlib/obj/gatherables/
skylib_fluffos_v3/mudlib/obj/instruments/
skylib_fluffos_v3/mudlib/obj/media/
skylib_fluffos_v3/mudlib/obj/misc/player_shop/
skylib_fluffos_v3/mudlib/obj/monster/godmother/
skylib_fluffos_v3/mudlib/obj/monster/transport/
skylib_fluffos_v3/mudlib/obj/rings/
skylib_fluffos_v3/mudlib/obj/scabbards/
skylib_fluffos_v3/mudlib/obj/spells/
skylib_fluffos_v3/mudlib/obj/stationery/
skylib_fluffos_v3/mudlib/obj/stationery/envelopes/
skylib_fluffos_v3/mudlib/obj/toys/
skylib_fluffos_v3/mudlib/obj/vessels/
skylib_fluffos_v3/mudlib/obj/weapons/axes/
skylib_fluffos_v3/mudlib/obj/weapons/chains/
skylib_fluffos_v3/mudlib/obj/weapons/maces/BACKUPS/
skylib_fluffos_v3/mudlib/save/autodoc/
skylib_fluffos_v3/mudlib/save/book_handler/
skylib_fluffos_v3/mudlib/save/books/history/calarien/
skylib_fluffos_v3/mudlib/save/mail/
skylib_fluffos_v3/mudlib/save/new_soul/data/
skylib_fluffos_v3/mudlib/save/parcels/
skylib_fluffos_v3/mudlib/save/playerinfo/
skylib_fluffos_v3/mudlib/save/players/d/
skylib_fluffos_v3/mudlib/save/players/s/
skylib_fluffos_v3/mudlib/save/random_names/
skylib_fluffos_v3/mudlib/save/random_names/data/
skylib_fluffos_v3/mudlib/save/terrains/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_desert/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_grassy_field/
skylib_fluffos_v3/mudlib/save/terrains/tutorial_mountain/
skylib_fluffos_v3/mudlib/save/todo_lists/
skylib_fluffos_v3/mudlib/secure/
skylib_fluffos_v3/mudlib/secure/cmds/admin/
skylib_fluffos_v3/mudlib/secure/cmds/lord/
skylib_fluffos_v3/mudlib/secure/config/
skylib_fluffos_v3/mudlib/secure/handlers/autodoc/
skylib_fluffos_v3/mudlib/secure/handlers/intermud/
skylib_fluffos_v3/mudlib/secure/include/global/
skylib_fluffos_v3/mudlib/secure/save/
skylib_fluffos_v3/mudlib/secure/save/handlers/
skylib_fluffos_v3/mudlib/secure/std/
skylib_fluffos_v3/mudlib/secure/std/classes/
skylib_fluffos_v3/mudlib/secure/std/modules/
skylib_fluffos_v3/mudlib/std/creator/
skylib_fluffos_v3/mudlib/std/dom/
skylib_fluffos_v3/mudlib/std/effects/
skylib_fluffos_v3/mudlib/std/effects/external/
skylib_fluffos_v3/mudlib/std/effects/fighting/
skylib_fluffos_v3/mudlib/std/effects/magic/
skylib_fluffos_v3/mudlib/std/effects/magic/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/other/BACKUPS/
skylib_fluffos_v3/mudlib/std/effects/priest/
skylib_fluffos_v3/mudlib/std/effects/room/
skylib_fluffos_v3/mudlib/std/environ/
skylib_fluffos_v3/mudlib/std/guilds/
skylib_fluffos_v3/mudlib/std/guilds/old/
skylib_fluffos_v3/mudlib/std/languages/
skylib_fluffos_v3/mudlib/std/liquids/
skylib_fluffos_v3/mudlib/std/npc/
skylib_fluffos_v3/mudlib/std/npc/goals/
skylib_fluffos_v3/mudlib/std/npc/goals/basic/
skylib_fluffos_v3/mudlib/std/npc/goals/misc/
skylib_fluffos_v3/mudlib/std/npc/plans/
skylib_fluffos_v3/mudlib/std/npc/plans/basic/
skylib_fluffos_v3/mudlib/std/npc/types/
skylib_fluffos_v3/mudlib/std/npc/types/helper/
skylib_fluffos_v3/mudlib/std/npcs/
skylib_fluffos_v3/mudlib/std/outsides/
skylib_fluffos_v3/mudlib/std/races/shadows/
skylib_fluffos_v3/mudlib/std/room/basic/BACKUPS/
skylib_fluffos_v3/mudlib/std/room/basic/topography/
skylib_fluffos_v3/mudlib/std/room/controller/
skylib_fluffos_v3/mudlib/std/room/inherit/topography/
skylib_fluffos_v3/mudlib/std/room/topography/area/
skylib_fluffos_v3/mudlib/std/room/topography/iroom/
skylib_fluffos_v3/mudlib/std/room/topography/milestone/
skylib_fluffos_v3/mudlib/std/shadows/curses/
skylib_fluffos_v3/mudlib/std/shadows/disease/
skylib_fluffos_v3/mudlib/std/shadows/fighting/
skylib_fluffos_v3/mudlib/std/shadows/healing/
skylib_fluffos_v3/mudlib/std/shadows/magic/
skylib_fluffos_v3/mudlib/std/shadows/poison/
skylib_fluffos_v3/mudlib/std/shadows/room/
skylib_fluffos_v3/mudlib/std/shops/controllers/
skylib_fluffos_v3/mudlib/std/shops/objs/
skylib_fluffos_v3/mudlib/std/shops/player_shop/
skylib_fluffos_v3/mudlib/std/socket/
skylib_fluffos_v3/mudlib/std/soul/d/
skylib_fluffos_v3/mudlib/std/soul/e/
skylib_fluffos_v3/mudlib/std/soul/i/
skylib_fluffos_v3/mudlib/std/soul/j/
skylib_fluffos_v3/mudlib/std/soul/k/
skylib_fluffos_v3/mudlib/std/soul/l/
skylib_fluffos_v3/mudlib/std/soul/n/
skylib_fluffos_v3/mudlib/std/soul/o/
skylib_fluffos_v3/mudlib/std/soul/q/
skylib_fluffos_v3/mudlib/std/soul/r/
skylib_fluffos_v3/mudlib/std/soul/u/
skylib_fluffos_v3/mudlib/std/soul/v/
skylib_fluffos_v3/mudlib/std/soul/y/
skylib_fluffos_v3/mudlib/std/soul/z/
skylib_fluffos_v3/mudlib/std/stationery/
skylib_fluffos_v3/mudlib/w/
skylib_fluffos_v3/mudlib/w/default/
skylib_fluffos_v3/mudlib/w/default/armour/
skylib_fluffos_v3/mudlib/w/default/clothes/
skylib_fluffos_v3/mudlib/w/default/item/
skylib_fluffos_v3/mudlib/w/default/npc/
skylib_fluffos_v3/mudlib/w/default/room/
skylib_fluffos_v3/mudlib/w/default/weapon/
skylib_fluffos_v3/mudlib/www/
skylib_fluffos_v3/mudlib/www/java/
skylib_fluffos_v3/mudlib/www/secure/
skylib_fluffos_v3/mudlib/www/secure/lpc/advanced/
skylib_fluffos_v3/mudlib/www/secure/lpc/intermediate/
skylib_fluffos_v3/win32/
/**
 * An nroff like object for formating text files.
 *<p>
 * This creates a saveable file format thingy.
 *
 * @author Pinkfish
 */
#include <nroff.h>

mixed *nroffed_file;
string nroffed_file_name;
int modified_time;
nosave int new_string;
nosave int force_string;

void create() {
  nroffed_file = ({ });
  seteuid("Root"); /* Security risk?  nahhhhh */
} /* create() */

#define do_bounds(bing) (bing<0?bing+cols:bing)

/**
 * Creates a string from a nroffed file.
 * <p>
 * If update is non zero it will look to see if the source file has been 
 * modified since the saved nroff file was created.  If it has, this
 * function returns 0 and the nroff file needs to be recreated.
 *
 * @param fname the file to process
 * @param update force update if file is newer?
 * @return the string representation of the nroff file
 */
string cat_file(string fname, int update) {
   int i, cols;
   string ret;
   
   if (!master()->valid_read(fname, geteuid(previous_object()),
                             "restore_object")) {
      return 0;
   }
   nroffed_file_name = 0;
   modified_time = 0;
   if (!restore_object(fname))
      return 0;
   if (!nroffed_file_name && update)
      return 0;
   if (update) {
      mixed *something;
      
      if (!master()->valid_read(nroffed_file_name,
                                geteuid(previous_object()),
                                "restore_object"))
         return 0;
      if (file_size(nroffed_file_name) <= 0)
         return 0;
      something = stat(nroffed_file_name);
      if (something[1] > modified_time)
         return 0;
   }
   ret = "";
   if (this_player()) {
      cols = (int)this_player()->query_cols() - 1;
   } else {
      cols = 79;
   }
   for (i=0;i<sizeof(nroffed_file);i++) {
      if (stringp(nroffed_file[i])) {
         ret += nroffed_file[i];
      } else {     
         switch (nroffed_file[i]) {
          case V_HEADER :
            ret += sprintf("%%^BOLD%%^%s%%^RESET%%^\n", nroffed_file[i+1]);
            i++;
            break;
          case V_CENTER :
            ret += sprintf("%|=*s", cols, nroffed_file[i+1]);
            i++;
            break;
          case V_ALL :
            ret += sprintf("%-*s%|*s%*s\n", nroffed_file[i+1],
                           nroffed_file[i+2],
                           cols - nroffed_file[i+1]*2,
                           nroffed_file[i+3],
                           nroffed_file[i+1],
                           nroffed_file[i+4]);
            i += 4;
            break;
          case V_INDENT :
            ret += sprintf( "%*=s%-=*s", nroffed_file[ i + 1 ], "",
                           cols - nroffed_file[ i + 1 ], nroffed_file[ i + 2 ] );
            i += 2;
            break;
          case V_PARA :
            if (nroffed_file[i+1])
            ret += sprintf("%*=s%-=*s%=*s\n", nroffed_file[i+1], "",
                           cols-nroffed_file[i+1]-
                           nroffed_file[i+2], nroffed_file[i+3],
                           nroffed_file[i+2], "");
            else if (nroffed_file[i+2])
            ret += sprintf("%-=*s%=*s\n", cols-nroffed_file[i+2],
                           nroffed_file[i+3],
                           nroffed_file[i+2], "");
            else
            ret += sprintf("%-=*s\n", cols, nroffed_file[i+3]);
            i += 3;
            break;
          case V_LEFT :
            ret += sprintf("%-=*s", cols, nroffed_file[i+1]);
            i++;
            break;
          case V_TABLE :
            ret += sprintf("%-#*s", cols, nroffed_file[i+1]);
            i++;
            break;
          case V_COLUMN : {
             int j;
             
             switch (sizeof(nroffed_file[i+1])) {
              case 2 :
                for (j=0;j<sizeof(nroffed_file[i+2]);j++)
                ret += sprintf("%*-=s%*-=s\n", do_bounds(nroffed_file[i+1][0]),
                               nroffed_file[i+2][j],
                               do_bounds(nroffed_file[i+1][1]),
                               nroffed_file[i+3][j]);
                i += 3;
                break;
              case 3 :
                for (j=0;j<sizeof(nroffed_file[i+2]);j++)
                ret += sprintf("%*-=s%*-=s%*-=s\n",
                               do_bounds(nroffed_file[i+1][0]),
                               nroffed_file[i+2][j],
                               do_bounds(nroffed_file[i+1][1]),
                               nroffed_file[i+3][j],
                               do_bounds(nroffed_file[i+1][2]),
                               nroffed_file[i+4][j]);
                i += 4;
                break;
             }
             break;
          }
         }
      }
   }
   return " \n"+ret;
} /* cat_file() */

/**
 * @ignore yes
 */
private string htmlify(string  str) {
  return replace(str, ({ "&", "&amp;", "<", "&lt;", ">", "&gt;"}));
} /* htmlify() */

/**
 * Turns the nroff file into a html output.  This works on nroff files
 * creating a html output from the mud source.
 *
 * @param file the name to process
 * @param title the title to give the document
 * @return the html file
 */
string html_file(string file, string title) {
   int i, j, cols, in_bold, in_italic;
   string ret, *bits;
   
   if (!master()->valid_read(file, geteuid(previous_object()),
                             "restore_object"))
      return 0;
   nroffed_file_name = 0;
   modified_time = 0;
   if (!restore_object(file))
      return 0;
   ret = "";
   cols = 78;

   for (i=0;i<sizeof(nroffed_file);i++)
     if (stringp(nroffed_file[i]))
       nroffed_file[i] = htmlify(nroffed_file[i]);
     else if(arrayp(nroffed_file[i])) {
       for (j=0;j<sizeof(nroffed_file[i]);j++)
         if(stringp(nroffed_file[i][j]))
           nroffed_file[i][j] = htmlify(nroffed_file[i][j]);
     }           

   
   for (i=0;i<sizeof(nroffed_file);i++) {
      if (stringp(nroffed_file[i])) {
         ret += "<h2>"+nroffed_file[i]+"</h2>";

#ifdef UNUSED         
         if(strsrch(nroffed_file[i], "See also") > -1) {
           for(j=i+1; j < sizeof(nroffed_file); j++) {
             if(stringp(nroffed_file[j])) {
               nroffed_file[j] = make_links(nroffed_file[j]);
             }
           }
         }
#endif         
      } else {
         switch (nroffed_file[i]) {
          case V_HEADER :
            ret += "<h2>"+replace_string(nroffed_file[i+1], "\n", "<br>")+
              "</h2>";
            i++;
            break;
          case V_CENTER :
            ret += "<center>"+replace(nroffed_file[i+1], "\n", "<br>")+
            "</center>";
            i++;
            break;
          case V_ALL :
            i += 4;
            break;
          case V_INDENT :
            ret += replace(nroffed_file[i+2], ({"<", "&lt;", ">",
               "&gt;", "\n", "<br>"}));
            i += 2;
            break;
          case V_PARA :
            ret += replace(nroffed_file[i+3], "\n", "<p>");
            i += 3;
            break;
          case V_LEFT :
            ret += "<left>"+nroffed_file[i+1]+"</left>";
            i++;
            break;
          case V_TABLE :
            ret += "<ul><li>"+replace(nroffed_file[i+1], "\n", "<li>")+"</ul>";
            i++;
            break;
          case V_COLUMN : {
             ret += "<table cellpadding=10>";
             switch (sizeof(nroffed_file[i+1])) {
              case 2 :
                for (j=0;j<sizeof(nroffed_file[i+2]);j++) {
                  ret += "<tr>\n";
                  ret += "<td nowrap>"+nroffed_file[i+2][j] + "</td>";
                  ret += "<td>"+nroffed_file[i+3][j] + "</td>";
                  ret += "</tr>";
                }
                i += 3;
                break;
              case 3 :
                for (j=0;j<sizeof(nroffed_file[i+2]);j++) {
                  ret += "<tr>\n";
                  ret += "<td nowrap>"+nroffed_file[i+2][j] + "</td>";
                  ret += "<td nowrap>"+nroffed_file[i+3][j] + "</td>";
                  ret += "<td>"+nroffed_file[i+4][j] + "</td>";
                  ret += "</tr>";
                }
                i += 4;
                break;
             }
             ret += "</table>";
             break;
          }
         }
      }
   }
   
   bits = explode(ret, "%^");
   ret = "";
   for (i=0;i<sizeof(bits);i+=2) {
      ret += bits[i];
    if (i+1 < sizeof(bits)) {
       switch (bits[i+1]) {
        case "BOLD" :
          if (!in_bold)
             ret += "<strong>";
          else
             ret += "</strong>";
          in_bold = !in_bold;
          break;
        case "RESET" :
          if (in_bold)
             ret += "</strong>";
          if (in_italic)
             ret += "</i>";
          in_bold = 0;
          in_italic = 0;
          break;
        default :
          if (!in_italic)
             ret += "<i>";
          else
             ret += "</i>";
          in_italic = !in_italic;
          break;
       }
    }
   }
   return ret;
} /* html_file() */

private void add_array(mixed *i) {
  if (!sizeof(nroffed_file))
    nroffed_file += ({ i });
  else if (force_string)
    nroffed_file += ({ "", i });
  else
    nroffed_file += ({ i });
  force_string = 0;
  new_string = 0;
} /* add_array() */

private void add_int(int i) {
  if (!sizeof(nroffed_file))
    nroffed_file += ({ i });
  else if (force_string)
    nroffed_file += ({ "", i });
  else
    nroffed_file += ({ i });
  force_string = 0;
  new_string = 0;
} /* add_int() */

private void add_string(string s) {
  if (!sizeof(nroffed_file) || new_string)
    nroffed_file += ({ s });
  else if (stringp(nroffed_file[<1]))
    nroffed_file[<1] += s;
  else
    nroffed_file += ({ s });
  new_string = 0;
  force_string = 0;
} /* add_string() */

/**
 * Makes the nroff saveable file.  Turns the input nroff file into a saved
 * output format.
 *
 * @param in_file the file name been processed
 * @param out_file the file to save it as
 * @return 1 if the operation was successful
 */
int create_nroff(string in_file, string out_file) {
  string text,
         tmp,
         *bits;
  string *bing;
  mixed  *cols;
  int strip_crs,
      col_mode,
      conv_tabs,
      i, j, k, fluff,
      num_cols;

  if (!master()->valid_read(in_file, geteuid(previous_object()),
                            "read_file"))
    return 0;
/*  if (!"/secure/master"->valid_write(out_file, geteuid(previous_object()),
                                    "save_object"))
    return 0; */
  nroffed_file_name = in_file;
  modified_time = time();
  text = read_file(in_file);
  if (!text)
    return 0;
    text = replace(text,"$MUDNAME$",mud_name());
  bits = explode("#\n"+text, "\n.");
  bits[0] = bits[0][1..];
  nroffed_file = ({ 0 });
  if (strlen(bits[0]))
    add_string(bits[0]);
  for (i=1;i<sizeof(bits);i++) {
/*
    if (!strlen(bits[i])) {
      if (col_mode) {
        for (j=0;j<num_cols;j++)
          cols[j] += "\n";
      } else if (strip_crs)
        add_string("\n\n");
      else
        add_string("\n");
    } else if (bits[i][0] == '.') {
 */
     if (sscanf(bits[i], "%s\n%s", tmp, bits[i]) != 2) {
        tmp = bits[i];
        bits[i] = "";
        fluff = 1;
     } else
        fluff = 0;
     switch (tmp[0..1]) {
      case "SH" : /* Section header */
        add_int(V_HEADER);
        add_string(tmp[3..]);
        new_string = 1;
        break;
      case "SI" : /* Start indent */
        add_int(V_INDENT);
        j = 0;
        sscanf(tmp[2..], "%d%s", j, tmp);
        add_int(j);
        force_string = 1;
        break;
      case "EI" : /* End indent */
        add_string("");
        new_string = 1;
        break;
      case "SP" : /* Start paragraph */
        add_int(V_PARA);
        j = 0;
        sscanf(tmp[2..], "%d%s", j, tmp);
        add_int(j);
        j = 0;
        sscanf(tmp, " %d%s", j, tmp);
        add_int(j);
        force_string = 1;
        strip_crs = 1;
        break;
      case "EP" : /* End paragraph */
        add_string("");
        new_string = 1;
        strip_crs = 0;
        break;
      case "SC" : /* start centering */
        add_int(V_CENTER);
        force_string = 1;
        break;
      case "EC" : /* End centering */
        new_string = 1;
        break;
      case "SL" : /* Start left justify */
        add_int(V_LEFT);
        force_string = 1;
        break;
      case "EL " : /* End left justify */
        new_string = 1;
        break;
      case "ST" : /* Start table mode (Turn tabs into new lines) */
        add_int(V_TABLE);
        force_string = 1;
        conv_tabs = 1;
        break;
      case "ET" : /* End table mode */
        new_string = 1;
        conv_tabs = 0;
        break;
      case "DT" : /* Do title.  Take the next three lines... */
        bing = explode(bits[i], "\n");
        if (sizeof(bing) < 3) {
           if (creatorp(TP)) {
              tell_object(this_player(), "Text file "+in_file+
                          " did not have enough lines after the .DT directive.\n");
              tell_object(this_player(), sprintf("%O\n", bing));
           }
           return 0; /* failed! */
        }
        add_int(V_ALL);
        if (strlen(bing[0]) > strlen(bing[2]))
           add_int(strlen(bing[0]));
        else
           add_int(strlen(bing[2]));
        new_string = 1;
        add_string("%^BOLD%^" + bing[0]);
        new_string = 1;
        add_string(bing[1]);
        new_string = 1;
        add_string(bing[2] + "%^RESET%^");
        new_string = 1;
        bits[i] = implode(bing[3..], "\n");
        break;
      case "SO" : /* starts column mode. The numbers after it
                   * are column size */
        num_cols = 0;
        tmp = tmp[2..];
        cols = ({ });
        while (sscanf(tmp, "%d%s", j, tmp) == 2) {
           cols += ({ j });
           num_cols++;
           while (strlen(tmp) && tmp[0] == ' ')
           tmp = tmp[1..];
        }
        add_int(V_COLUMN);
        if (sscanf(tmp, "%d", j) == 1) {
           cols += ({ j });
           num_cols++;
        }
        add_array(cols);
        cols = allocate(num_cols);
        for (j=0;j<num_cols;j++) cols[j] = ({ });
        col_mode = 1;
        break;
      case "EO" : /* End column mode */
        for (j=0;j<num_cols;j++) {
           add_array(cols[j]);
        }
        col_mode = 0;
        break;
      case "NF" : /* New File.  Take the next line and ignore everything
                   * else in the file */
        bing = explode(bits[i], "\n");
        if (sizeof(bing) < 1) {
           if (creatorp(TP)) {
              tell_object(this_player(), "Text file "+in_file+
                          " did not have enough lines after the .NF directive.\n");
              tell_object(this_player(), sprintf("%O\n", bing));
           }
           return 0; /* failed! */
        }
        /* read the new file and start again, but keep the old name */
        text = read_file(bing[ 0 ]);
        if (!text)
          return 0;
        bits = explode("#\n"+text, "\n.");
        bits[0] = bits[0][1..];
        nroffed_file = ({ 0 });
        if (strlen(bits[0]))
           add_string(bits[0]);
        strip_crs = col_mode = conv_tabs = fluff = num_cols = i = 0;
        break;
     }
     if (fluff) continue;
     if (conv_tabs)
        bits[i] = replace(bits[i], "\t", "\n");
     if (col_mode) {
        string *frog;
        
        frog = explode(bits[i], "\n");
        for (k=0;k<sizeof(frog);k++) {
           bing = explode("#"+frog[k], "\t");
           bing[0] = bing[0][1..];
           for (j=0;j<num_cols && j < sizeof(bing);j++)
              cols[j] += ({ bing[j] });
           for (j=sizeof(bing);j<num_cols;j++)
              cols[j] += ({ "\n" });
        }
     } else if (strip_crs) {
        bits[i] = replace_string(bits[i], "\n\n", "$%^NeW_LiNe^%$");
        bits[i] = replace_string(bits[i], ".\n", ".  ");
        bits[i] = replace_string(bits[i], "\n", " ");
        bits[i] = replace_string(bits[i], "$%^NeW_LiNe^%$", "\n\n");
        add_string(bits[i]+" ");
     } else
        add_string(bits[i]+"\n");
     /*
      }
      */
  }
  new_string = 0;
  force_string = 0;
  unguarded((: save_object, out_file :));
  return 1;
} /* create_nroff() */

/*
void create_help(string path, string file) {
  if (path[0..4] == "/doc/")
    this_object()->create_nroff(path+file, NROFF_DIR+file);
  else
    write("Invalid path. "+path+"\n");
}

void create_chelp(string path, string file) {
  if (path[0..4] == "/doc/")
    this_object()->create_nroff(path+file, CNROFF_DIR+file);
  else
    write("Invalid path.\n");
}

void create_man(string path, string file) {
  if (path[0..4] == "/doc/")
    this_object()->create_nroff(path+file, MNROFF_DIR+file);
  else
    write("Invalid path.\n");
} */

/**
 * Will attempt to find the name of the nroffed file.  Will attempt to
 * find the name of the source file associated with the save file.
 *
 * @param fname the name of the file to check
 * @return the source file name or 0
 */
string query_file_name( string fname ) {
   if (!master()->valid_read(fname, geteuid(previous_object()),
                             "restore_object"))
      return 0;
   nroffed_file_name = 0;
   modified_time = 0;
   if (!restore_object(fname))
      return 0;
   return nroffed_file_name;
} /* query_file_name() */