ANSI Colors

Citadel supports both ANSI codes and a Citadel-specific
method of changing colors that is a bit easier to use. To
turn on this support, use the Terminal settings (T)
subcommand of the .Enter Configuration (.EC) command. There
are two choices for turning on ANSI available from this
subcommand: ANSI mode (A)  and ANSI color (C) . Turning on
ANSI mode tells Citadel to display certain things with ANSI
(such as room prompts and message headers). It also tells
Citadel to pass the Citadel-specific Control+A codes (see
below) 0 to 4 to you. Turning on ANSI color tells Citadel to
pass the Control+A codes a-h and A-H to you.

Turning on either also tells Citadel to pass ANSI (ESC[...)
codes to you. Otherwise, it strips these out, in an attempt
to keep the text visible to you. (It works well as long as
the only ANSI codes are color changes, not cursor movement.)

Citadel's Control+A color codes start with a Control+A
(ASCII 1) and then a character that specifies the new color
or other attribute. The available characters are:

          Code   Result
          0      Normal
          1      Blink
          2      Reverse
          3      Bold (high intensity)
          4      Underline
          a      Black foreground
          A      Black background
          b      Red foreground
          B      Red background
          c      Green foreground
          C      Green background
          d      Yellow foreground
          D      Yellow background
          e      Blue foreground
          E      Blue background
          f      Magenta foreground
          F      Magenta background
          g      Cyan foreground
          G      Cyan background
          h      White foreground
          H      White background
          r       Random foreground
          R      Random background
          
You can change the actual ANSI codes that Citadel passes to
your terminal for the codes 0-4 by using the Attributes (R)
choice of the Terminal settings (T)  subcommand of the
.Enter Configuration (.EC) command.

Underline (Control+A4) usually does not appear as an
underline: the text modes of IBM PC video cards that support
color (CGA, EGA, VGA) do not support underlined text. The
ANSI terminal code that enables underlined text on these
cards sets the text color to blue. (Or, more accurately, to
generate underlined text on the MDA, you specify the text
color as blue.)

You can also mix Control+A3 with the a-h codes to make the
colors brighter. To do this, enter the Control+A3 before the
Control+Aletter. Similarly, mixing Control+A1 with the codes
A-H will make the characters blink in the specified color.
Control+A2 (reverse) and Control+A4 (underline) cannot be
mixed with the other colors like this: the color code
entered will override the reverse or underline attribute.

Message Command Interpreter (MCI) Commands

If you have MCI (Message Command Interpreter) turned on with
the #TWIT_FEATURES keyword of CONFIG.CIT, messages can
become much more than just text: they can be interactive
sessions for the user.

Like colors (see the "ANSI Colors" section), MCI commands
all start with Control+A. A few MCI commands are a single
character long, like the colors, but most are multiple
characters. Multiple character commands all start with X and
end with X; the X at the start tells Citadel that this is an
extended command, and the X at the end tells Citadel that it
has reached the end of the command. For example, the command
to display the current connect rate is "^AXcrX". The "^A" is
the Control+A that tells Citadel that a special formatting
code (color or MCI) is next. The first "X" tells Citadel
that this is an extended code. The "cr" stands for "Connect
Rate" and actually tells Citadel what to display. The final
"X" tells Citadel that this is the end of the extended
command.


Variables
There are 10 variables that can hold string values and 10
that can hold character values. The variables holding string
values can also be used to hold numeric values. The
variables are labeled 0 to 9.

To assign a value to a string variable, use the Assign
(^AXas{variable}{value}X) command. To get the output of any
MCI command into a string variable, use the Assign next
(^AXan{variable}X) command. To get user input into a string,
use the Get string (^AXgs{variable}X) command. String
variables can be displayed using the Put string
(^AXps{variable}X) command.

Character variables can only be assigned to a user's
keystroke, with the Get character (^AXgc{variable}X)
command. Character variables can be displayed using the Put
character (^AXpc{variable}X) command.

The value of a variable can be tested with the Compare
(^AXcm{variable}[vflag]{type}{value}X) command, then acted
on with the Equal to (^AXeq{command}X), Greater than
(^AXgt{command}X), and Less than (^AXlt{command}X) commands.


The commands
All commands with an "*" after them are not yet implemented.

     Account balance (^AXabX)
          This displays the current user's account balance.
          
     Add (^AX++{result variable}{variable 1}{variable
          2...}X)
          This command looks at string variables as if they
          were numeric, and adds {variable 1} to {variable
          2} (and to {variable 3}, etc., if present) and
          assigns the value to {result variable}. For
          example, the command "^AX++394123X" would assign
          the sum of string variable 9 plus string variable
          4 plus string variable 1 plus string variable 2
          plus string variable 3 to string variable 3.
          
     Address (^AXad{#}X)
          This displays the current user's address. The
          value of {#} determines which line to display: 1,
          2, or 3. If no user is logged-in, this displays
          "Not logged in" for all three.
          
     Assign (^AXas{variable}{value}X)
          This assigns the value given by {value} to the
          string variable number {variable}.
          
     Assign next (^AXan{variable}X)
          This assigns the output of the next MCI command to
          the string variable number {variable}, instead of
          displaying to the user.
          
     Backspace (^AXbs{#}X)
          This sends backspace (Control+H) characters to the
          user. The value of {#} determines how many to
          send.
          
     Beep (^AXbp{#}X)
          This sends bell (Control+G) characters to the
          user. The value of {#} determines how many to
          send.
          
     Call number * (^AXcnX)
          
          This sends the current call number.
          
     Clear screen *(^AXclX)
          This clears the screen.
          
     Compare (^AXcm{variable}[vflag]{type}{value}X)
          This does a comparison of a variable to {value}.
          The type of comparison is determined by {type}: if
          it is "N" then a numeric comparison between
          {value} and the string variable number {variable}
          is made; if it is "C" then an alphabetic
          comparison between the character variable number
          {variable} and {value} is made; otherwise an
          alphabetic comparison between the string variable
          number {variable} and {value} is made. The
          alphabetic comparisons are not case sensitive: the
          strings "abc" and "ABC" are considered equal.
          
          [vflag] should be set to "V" if you want {value}
          to address a variable, or omitted if you want
          {value} to be treated literally by Citadel. That
          is, the MCI command "^AXcm0S9X" will compare
          string variable 0 to the string "9" and MCI
          command "^AXcm0VS9X" will compare string variable
          0 to string variable 9.
          
          To use the result of a comparison, use the Greater
          Than, Less Than, and Equal To commands, which are
          described below.
          
     Connect rate (^AXcrX)
          This displays the connect rate.
          
     Disk free * (^AXdf{drive}X)
          This shows how much disk space is free on
          {drive}:. For the drive of the current room's
          directory, use "0" for {drive}. For the drive of
          the #HOMEPATH as set in CONFIG.CIT, use "1" for
          {drive}. Otherwise, use a letter from "A" to "Z".
          
     Divide (^AX//{result variable}{variable 1}{variable
          2...}X)
          This command looks at string variables as if they
          were numeric, and divides {variable 1} by
          {variable 2} (and by {variable 3}, etc., if
          present) and assigns the value to {result
          variable}. For example, the command "^AX//394123X"
          would assign the quotient of string variable 9
          divided by string variable 4 divided by string
          variable 1 divided by string variable 2 divided by
          string variable 3 to string variable 3.
          
     Equal to (^AXeq{command}X)
          This executes the MCI command {command} if the
          last Compare (see above) command resulted in
          equivalence. Don't put an "X" at the start of
          {command}. Otherwise, Citadel will interpret this
          as the end of the "eq" command. If you need to do
          a non-extended command in response to an Equal to
          command, you must use the Goto command to go to
          it. For example, this will display the current
          room name (see the Room Name command below) if the
          last Compare command ended in an equivalency:
          "^AXeqrmX". Notice that there is no X before the
          "rm" part of the command, only after it.
          
     First name (^An)
          
          This attempts to display the user's first name. It will
          display full names of users like "The Hidden" who
          have "The", "A", or "An" as their first names.
          
     Get character (^AXgc{variable}X)
          This gets a single character from the user and
          stores it in character variable number {variable}.
          The character is not displayed by Citadel.
          
     Get string (^AXgs{variable}X)
          This gets a string from the user and stores it in
          string variable number {variable}. The string is
          displayed as the user enters it.
          
     Goto label (^AXgo{label}X)
          This makes the output flow jump to the label
          specified by {label}. This command does not work
          if the output is not stoppable by the user (such
          as in a room prompt).
          
     Greater than (^AXgt{command}X)
          This executes the MCI command {command} if the
          result of the last Compare command was greater
          than. The {command} should not start with an "X"
          as that is not part of the MCI command, but a
          special character that tells Citadel where an MCI
          command starts and ends. For example, the command
          "^AXgtgowowX" will transfer the output flow to the
          label "wow" if that last Compare command resulted
          in a greater than.
          
     Hall name (^AXhnX)
          This outputs the name of the current hall.
          
     Initials (^AXinX)
          This outputs the initials the current user uses to
          log into the board.
          
     Label (^AXlb{label}X)
          This is a place holder, used by the Goto label
          command. It does nothing by itself.
          
     Last call time/date (^AXlcX)
          This displays the user's last call time and date,
          using the current verbose time/date format string.
          
     Last name (^AXlnX)
          This attempts to display the user's last name.
          Citadel does this by searching backwards from the
          end of the name for the first space. Anything
          after the first space it finds (or the whole name
          if there is no space) is thought to be the last
          name.
          
     Less than (^AXlt{command}X)
          This executes the MCI command {command} if the
          result of the last Compare command was less than.
          The {command} should not start with an "X" as that
          is not part of the MCI command, but a special
          character that tells Citadel where an MCI command
          starts and ends. For example, the command
          "^AXltgowowX" will transfer the output flow to the
          label "wow" if that last Compare command resulted
          in a less than.
          
     Messages in room (^AXmrX)
          
          This displays the number of messages in the current
          room, as is displayed when going to it.
          
     Multiply (^AX**{result variable}{variable 1}{variable
          2...}X)
          This command looks at string variables as if they
          were numeric, and multiplies {variable 1} by
          {variable 2} (and by {variable 3}, etc., if
          present) and assigns the value to {result
          variable}. For example, the command "^AX**394123X"
          would assign the product of string variable 9
          times string variable 4 times string variable 1
          times string variable 2 times string variable 3 to
          string variable 3.
          
     Node name (^AXnnX)
          This displays the name of the current node.
          
     Node phone number (^AXnpX)
          This displays the phone number of the current
          node.
          
     Non-verbose Time/Date (^At)
          
          This displays the current time/date using the non-
          verbose time/date stamp.
          
     Number read * (^AXnmX)
          This displays the total number of messages read
          this call.
          
     Out special * (^AXos#X)
          Wow. This has not yet been implemented.
          
     Password (^AXpwX)
          This displays the password the current user uses
          to log on.
          
     Phone number (^AXpnX)
          This displays the phone number of the current
          user.
          
     Poopcount (^AP)
          This displays the poopcount of the current user.
          
     Poopuser * (^Ap)
          
          This displays the current poopuser of the board.
          
     Port rate (^AXprX)
          This displays the current port rate.
          
     Put character (^AXpc{variable}X)
          This displays the contents of character variable
          number {variable}.
          
     Put string (^AXps{variable}X)
          This displays the contents of string variable
          number {variable}.
          
     Random number (^AXrd{variable}#X)
          This assigns a random number in the range of 1 to
          # to string variable number {variable}.
          
     Real name (^AXrnX)
          This displays the real name of the current user.
          
     Room name (^AXrmX)
          This displays the current room name.
          
     Slow output * (^AXsl#X)
          Wow. This has not yet been implemented.
          
     Subtract (^AX--{result variable}{variable 1}{variable
          2...}X)
          This command looks at string variables as if they
          were numeric, and subtracts {variable 2} from
          {variable 1} (and {variable 3} from that
          difference, etc., if present) and assigns the
          value to {result variable}. For example, the
          command "^AX--394123X" would assign the difference
          of string variable 9 minus string variable 4 minus
          string variable 1 minus string variable 2 minus
          string variable 3 to string variable 3.
          
     Sysop name (^AXsnX)
          This displays the name of the console sysop, as
          set by #SYSOP in CONFIG.CIT.
          
     User name (^AN)
          This displays the current user's full name.
          
     Verbose Time/Date (^AT)
          
          This displays the current time/date using the verbose
          time/date stamp.
          

Examples
To create complex MCI messages with looping and branching,
you almost need to use a text editor, unless you are really
good about keeping things in your mind. In the following
examples, the character "" is used for Control+A. (Control+A
will show up as a smiley face in your text editor.) Also, as
you often need to enter many characters without pressing the
Enter key to make the formatting come out correctly, each
line is entered with a hanging indent.

The following message would give the user a message based on
his poopcount:

     Hey, n, youXan0XPXcm0N0XXltgonegativeXXcm0N100XXltgosma
                    llXXcm0N1000XXltgomedXXcm0N10000XXltgola
                    rgeX have a lot of poop!XgoendX
     XlbnegativeXr poop comes out backwards!XgoendX
     XlbsmallX should poop more.XgoendX
     XlbmedX just barely poop enough.XgoendX
     XlblargeX are pretty good about pooping.XlbendX
     
This message starts with the text "Hey, n, you", which is
always displayed. This lets the user see that it is directed
at him by including his name in the message. After that,
Citadel does some comparisons and branching to display the
rest of the message based on the user's poopcount. As we
don't want to output a carriage return in the middle of
this, it all has to be on the same line. If your text editor
takes you to the next line when you fill up the first, then
you have word-wrap mode turned on. You should turn it off so
that the message looks correct when it is loaded into
Citadel.

The first thing this message does after printing the
introduction text is use the Assign Next command and the
Poopcount command to assign the user's poopcount to variable
number 0. This is the "Xan0XP" in the message.

After this, the message performs the first comparison:
"Xcm0N0X". This compares the value of variable 0 (which we
just loaded with the user's poopcount) with the number 0.
Then we act on the comparison: "XltgonegativeX" branches to
the label "negative" if the variable 0 contains a value less
than 0. If the value is not less than zero, then display of
the message continues with the next comparison: "Xcm0N100X".
This compares the value of variable 0 with the number 100.
As before, this is acted on with the Less Than command:
"XltgosmallX" branches to the label "small" if the value is
less than 100. This continues similarly, checking for a
value of under 1,000 (which branches to the label "med"),
then a value of under 10,000 (which branches to the label
"large").

If the user's poopcount is 10,000 or greater, then the text
" have a lot of poop!" is displayed. This, when combined
with the "Hey, n, you" that has already been displayed to
the user, creates the full message "Hey, n, you have a lot
of poop!" After the message is displayed, the Goto command
"XgoendX" is used to skip to the end of the message.

At this point in the message, any text entered would never
be displayed. That is because there was an unconditional
Goto just previous: there is no way that this section of the
message will ever be displayed. Because of this, we can
press Enter here and move to the next line (just to keep
things close to readable in the text editor) without having
an effect on the formatted output.

Then we have our first Label: "XlbnegativeX". This gives a
destination to go to when the user's poopcount is less than
0 (remember the first comparison done in the message). This
starts by outputting the text "r poop comes out backwards!"
This, when combined with the first part of the message
already displayed, forms the message: "Hey, n, your poop
comes out backwards!" (You'd understand if your poopcount
was less than 0.) After the message is displayed, the Goto
command "XgoendX" skips to the end of the message.

Again, we are now in a place of the message that will never
be displayed to the user. Because of this, we can start a
new line to keep things close to readable. This new line is
just the label "small" and the rest of the message that
should be displayed to people with a poopcount of less than
100 but not less than 0, followed by a Goto that skips to
the end of the message. This is repeated for people with a
poopcount of less than 1,000 but not less than 100, with the
label "med".

Finally, the label "large" is used for the message to
display to uses with a poopcount of less than 10,000 but not
less than 1,000. At the end of this message, however, we
don't have a Goto command that skips to the end of the
message: we have the "end" Label that we have been skipping
to previously.

At this point, you can enter anything more in the message
that you want to display to all users. However, we just end
the message here, so nothing more is done.


