! ---------------------------------------------------------------------------
!       printf("string", values...)             ! print formatted
!
!       printf("The %o jumped over the %s %n times.", objectCow, "moon", 5)
!       printf("The user entered the '%c' key.", ch)
!       printf("%#Please pass the %o,%# said the %o.", objectSalt, objectElf) !double quotes
!       printf("Note the <b>warning</b>!")              ! bold (or italics or underline)
!
!               regular text                    printchar                               text in primary string
!               %c      character                       printchar                               character
!               %d      decimal number          print number                    decimal integer
!               %h      hexadecimal number      print hex                               word in hex
!               %o      object                          print object.name               object name
!               %s      string                          print string                    dictionary entry
!               html:
!               %#      double-quote            printchar '"'                   double-quote (open)
!               %%      '%'                                     printchar                               percent character
!               %;      no newline at end       no newline                              override default newline
!               %n      newline                         print newline                   overt newline at position
!               <b> font bold                   Font()                                  set bold font
!               </b> font bold off              Font()                                  set bold font off
!               <i> font italics                Font()                                  set italics font
!               </i> font italics off   Font()                                  set italics font off
!               <u> font underline              Font()                                  set underline font
!               </u> font underline off Font()                                  set underline font off
!
!       Notes:  a newline is printed at the end of the line, unless "%:" is in the line.
!                       Values %c %d %h %o %s should be matched by a value in the matching position.
!                       0 to 9 %-values (with matching operands) are handled.
!                       More than 9 %-values will result in default values of zero.
!                       Items %# %% %; %n <b> <i> <u> </b> </i> </u> do not match operands.
array printf_array[10]          ! work array
!----------------------------------------------------------------------------
routine printf(str, v1, v2, v3, v4, v5, v6, v7, v8, v9)
{       local c, i, k, lens, n, nl
       ! put the operands in the work array:
       printf_array[1] = v1
       printf_array[2] = v2
       printf_array[3] = v3
       printf_array[4] = v4
       printf_array[5] = v5
       printf_array[6] = v6
       printf_array[7] = v7
       printf_array[8] = v8
       printf_array[9] = v9
       k=1                     ! point to the first operand
       lens = string(_temp_string, str, 255)   ! convert base text to a work string

       for (i=0 ; i<lens; )                    ! for each character of the primary string
       {       c = _temp_string[i++]           !   get the next character
               if c='%'        ! if current byte is '%'
               {       c = _temp_string[i++]           !   get the following character (format code)
                       select c                                                                        ! per format character:
                       case '%':       printchar '%'                                   !   print a literal '%'
                       case '#':       printchar '"'                                   !   print a double-quote
                       case 'd':       print number printf_array[k++]; !   print a decimal number
                       case 'h':       print hex printf_array[k++];    !   print a hexadecimal number
                       case 'n':       print newline                                   !   print a line break
                       case 'o':       print printf_array[k++].name;   !   print an object name
                       case ';':       nl=true                                                 !   set no-newline flag
                       case 'c'
                       {       n=printf_array[k++]                     ! print a character
                               if n>=32 and n<=126: printchar(n)
                               else: print number n;
                       }
                       case 's'
                       {       print printf_array[k++];                ! print the inner-string
                       }
                       case else                       ' %-escape char not recognized
                       {       printchar '%'   !   so just print '%' and char
                               printchar c
                       }
                       ! end select
                       if k>10: "\n<ERROR: printf() too many operands (max is 9)"
               }
               elseif c='<'    ! if current byte is '<'                ! check for HTML
               {       if _temp_string[i]='b' and _temp_string[i+1]='>'
                       {       Font(BOLD_ON)
                               i=i+2
                       }
                       elseif _temp_string[i]='i' and _temp_string[i+1]='>'
                       {       Font(ITALIC_ON)
                               i=i+2
                       }
                       elseif _temp_string[i]='u' and _temp_string[i+1]='>'
                       {       Font(UNDERLINE_ON)
                               i=i+2
                       }
                       elseif _temp_string[i]='/' and _temp_string[i+1]='b' and _temp_string[i+2]='>'
                       {       Font(BOLD_OFF)
                               i=i+3
                       }
                       elseif _temp_string[i]='/' and _temp_string[i+1]='i' and _temp_string[i+2]='>'
                       {       Font(ITALIC_OFF)
                               i=i+3
                       }
                       elseif _temp_string[i]='/' and _temp_string[i+1]='u' and _temp_string[i+2]='>'
                       {       Font(UNDERLINE_OFF)
                               i=i+3
                       }
                       else                    ! got a '<', but it wasn't a proper font-html sequence
                       {       printchar c     !   so just print the '<'
                       }
               }
               else                            ! if the current byte is neither '%' nor '<'
                       printchar c             !   just print it
       }
       if nl=false: print newline              ! print line break
}