home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / xwplascr.zip / XWPL0208.ZIP / release / bin / xhelp.cmd < prev    next >
OS/2 REXX Batch file  |  2000-01-04  |  23KB  |  653 lines

  1. /* XHELP.CMD
  2.  *
  3.  * This is CommandPak's xhelp command.
  4.  *
  5.  * (w) (c) 1997-98 Ulrich Möller. All rights reserved.
  6.  */
  7.  
  8. '@echo off'
  9.  
  10. signal on halt
  11.  
  12. nl = '0d0a'x           /* this is CR+LF (hex), helpful for defining help strings */
  13. extLevel = 0
  14.  
  15. helpList. = ''
  16. helpList.ALIAS = 'call msg getExtMsg("aliasHelp")'
  17. helpList.CD = 'call msg getExtMsg("cdHelp"), "cd"'
  18. helpList.CMDSHL = 'call msg getExtMsg("cmdshlHelp")'
  19. helpList.COPY = 'call msg getExtMsg("copyHelp"), "copy"'
  20. helpList.CP = 'call msg getExtMsg("copyHelp"), "cp"'
  21. helpList.DEF = 'call msg getExtMsg("defineHelp"), "def"'
  22. helpList.DEFINE = 'call msg getExtMsg("defineHelp"), "define"'
  23. helpList.DEL = 'call msg getExtMsg("delHelp"), "del"'
  24. helpList.DIR = 'call msg getExtMsg("dirHelp"), "dir"'
  25. helpList.EXIT = 'call msg getExtMsg("exitHelp")'
  26. helpList.HELP = 'call msg getExtMsg("helpHelp"), "help"'
  27. helpList.FL = 'call startView help.ref filelist'
  28. helpList.FOR = 'call msg getExtMsg("forHelp")'
  29. helpList.KEYS = 'call msg getExtMsg("keysHelp")'
  30. helpList.LN = 'call msg getExtMsg("lnHelp")'
  31. helpList.LS = 'call msg getExtMsg("dirHelp"), "ls"'
  32. helpList.LESS = 'call startView help.ref less'
  33. helpList.MV = 'call msg getExtMsg("renHelp"), "mv"'
  34. helpList.OPEN = 'call msg getExtMsg("openHelp")'
  35. helpList.PUSHD = 'call msg getExtMsg("pushdHelp")'
  36. helpList.POPD = 'call msg getExtMsg("pushdHelp")'
  37. helpList.QUERY = 'call msg getExtMsg("queryHelp")'
  38. helpList.QUIT = 'call msg getExtMsg("quitHelp")'
  39. helpList.REC = 'call msg getExtMsg("recurseHelp")'
  40. helpList.RECURSE = 'call msg getExtMsg("recurseHelp")'
  41. helpList.REN = 'call msg getExtMsg("renHelp"), "ren"'
  42. helpList.RULE = 'call msg getExtMsg("ruleHelp")'
  43. helpList.RX = 'call msg getExtMsg("rxHelp")'
  44. helpList.SDIR = 'call startView help.ref sdir'
  45. helpList.VER = 'call msg getExtMsg("versionMsg")'
  46. helpList.WATCHDRV = 'call msg getExtMsg("watchdrvHelp")'
  47. helpList.XCP = 'call msg getExtMsg("copyHelp"), "xcp"'
  48. helpList.XDEL = 'call msg getExtMsg("delHelp"), "xdel"'
  49. helpList.XDIR = 'call msg getExtMsg("dirHelp"), "xdir"'
  50. helpList.XHELP = 'call msg getExtMsg("helpHelp"), "xhelp"'
  51. helpList.XREN = 'call msg getExtMsg("renHelp"), "xren"'
  52. helpList._XRENEXPL = 'call msg getExtMsg("renExpl")'
  53.  
  54. escapeList.437 = 'auml=ä euml=ë iuml=ï ouml=ö uuml=ü Auml=Ä Ouml=Ö Uuml=Ü',
  55.     'aacute=á eacute=é iacute=í oacute=ó uacute=ú Eacute=É',
  56.     'agrave=à egrave=è egrave=ì ograve=ò ugrave=ù',
  57.     'acirc=â ecirc=ê icirc=î ocirc=ô ucirc=û',
  58.     'aring=å Aring=Å ntilde=ñ Ntilde=Ñ iexcl=¡ ccedil=ç Ccedil=Ç szlig=ß ',
  59.     'sect= frac14=¼ frac12=½ sup2=² sub3=ⁿ aelig=æ AElig=Æ pound=£ cent=¢ para= micro=µ lt=< gt=> amp=& quot=" nbsp= ',
  60.     'curren= plusmn=± laquo=« raquo=» uarrw= darrw= larrw= rarrw=',
  61.     /* now the codepage-specific ones */,
  62.     'Euml=E Iuml=I Aacute=A Iacute=I Oacute=O Uacute=U Agrave=A Egrave=E Igrave=I Ograve=O Ugrave=U',
  63.     'Ecirc=E Icirc=I Acirc=A Ocirc=O Ucirc=U yen=¥'
  64.  
  65. escapeList.850 = 'auml=ä euml=ë iuml=ï ouml=ö uuml=ü Auml=Ä Ouml=Ö Uuml=Ü',
  66.     'aacute=á eacute=é iacute=í oacute=ó uacute=ú Eacute=É',
  67.     'agrave=à egrave=è egrave=ì ograve=ò ugrave=ù',
  68.     'acirc=â ecirc=ê icirc=î ocirc=ô ucirc=û',
  69.     'aring=å Aring=Å ntilde=ñ Ntilde=Ñ iexcl=¡ ccedil=ç Ccedil=Ç szlig=ß ',
  70.     'sect= frac14=¼ frac12=½ sup2=² sub3=ⁿ aelig=æ AElig=Æ pound=£ cent=¢ para= micro=µ lt=< gt=> amp=& quot=" nbsp= ',
  71.     'curren= plusmn=± laquo=« raquo=» uarrw= darrw= larrw= rarrw=',
  72.     /* now the codepage-specific ones */,
  73.     'Euml=╙ Iuml=╫ Aacute=╡ Iacute=╓ Oacute=α Uacute=Θ Agrave=╖ Egrave=╘ Igrave=▐ Ograve=π Ugrave=δ',
  74.     'Ecirc=╥ Icirc=╫ Acirc=╢ Ocirc=Γ Ucirc=Ω yen=Y'
  75.  
  76. /* support for cp 852 added by Tomas Hajny, XHajT03@mbox.vol.cz */
  77. escapeList.852 = 'auml=ä euml=ë iuml=i ouml=ö uuml=ü Auml=Ä Ouml=Ö Uuml=Ü',
  78.     'aacute=á eacute=é iacute=í oacute=ó uacute=ú Eacute=É',
  79.     'agrave=a egrave=e igrave=i ograve=o ugrave=u',
  80.     'acirc=â ecirc=e icirc=î ocirc=ô ucirc=u',
  81.     'aring=a Aring=A ntilde=n Ntilde=N iexcl=! ccedil=ç Ccedil=Ç szlig=ß ',
  82.     'sect= frac14=/ frac12=/ sup2=2 sup3=3 aelig=e AElig=E pound=L cent=c para= micro=u lt=< gt=> amp=& quot=" nbsp= ',
  83.     'curren= plusmn=/ laquo=« raquo=» uarrw= darrw= larrw= rarrw=',
  84.     /* now the codepage-specific ones */,
  85.     'Euml=╙ Iuml=╫ Aacute=╡ Iacute=╓ Oacute=α Uacute=Θ Agrave=A Egrave=E Igrave=I Ograve=O Ugrave=U',
  86.     'Ecirc=E Icirc=╫ Acirc=╢ Ocirc=Γ Ucirc=U yen=Y'
  87.  
  88. sysMsgList = 'SYS REX' /* list of prefixes to system messages */
  89.  
  90. call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
  91. call SysLoadFuncs
  92.  
  93. /* first detect colors out of environment vars */
  94. ansiReset = ""
  95.  
  96. /* coloring for <A HREF=""> */
  97. val = value('HELP.ANCHOR',,'OS2ENVIRONMENT')
  98. if (val \= "") then do
  99.     ansiAnchorOn = ansiValue(val)
  100.     ansiReset = '1b'x||'[0m'
  101. end
  102. else
  103.     ansiAnchorOn = ""
  104.  
  105. /* coloring for <B> */
  106. val = value('HELP.BOLD',,'OS2ENVIRONMENT')
  107. if (val \= "") then do
  108.     ansiBoldOn = ansiValue(val)
  109.     ansiReset = '1b'x||'[0m'
  110. end
  111. else
  112.     ansiBoldOn = ""
  113.  
  114. /* coloring for <I> */
  115. val = value('HELP.ITALICS',,'OS2ENVIRONMENT')
  116. if (val \= "") then do
  117.     ansiItalicsOn = ansiValue(val)
  118.     ansiReset = '1b'x||'[0m'
  119. end
  120. else
  121.     ansiItalicsOn = ""
  122.  
  123. /* default color for <I> */
  124. val = value('HELP.COLOR',,'OS2ENVIRONMENT')
  125. if (val \= "") then
  126.     ansiReset = '1b'x||'[0m'ansiValue(val)
  127.  
  128. imageString = ansiItalicsOn''
  129.  
  130. /* now process args */
  131.  
  132. parse arg args
  133.  
  134. _upper = 'helpList.'||translate(word(args, 1))
  135.  
  136. parse var args opt parameters
  137.  
  138. select
  139.   when (opt = '-c') then
  140.     call msg getExtMsg("cmdshlHelp")
  141.   when (opt = "") then
  142.     call msg getExtMsg("helpHelpFirst")
  143.   when (opt = '?') | (opt = '/?') | (opt = '-h') then
  144.     call msg getExtMsg("helpHelp"), "help"
  145.   when (opt = '-x') | (opt = '-X') then
  146.     call msg getExtMsg("helpHelpExampl"), "help"
  147.   when (opt = '-w') then
  148.     call msg getExtMsg("welcomeMsg")
  149.   when (opt = '-f') then
  150.     call msg getExtMsg(word(parameters, 1)), word(parameters, 2)
  151.   when (opt = '-F') then
  152.     call msg extractMsg(word(parameters, 1), word(parameters, 2)), word(parameters, 3)
  153.   /* output text directly */
  154.   when left(args, 1) = '"' then do
  155.     p2 = lastpos('"', args)
  156.     if p2 > 2 then
  157.         args = substr(args, 2, p2-2)
  158.         else do; call charout , SysGetMessage(1003); exit; end
  159.     call msg args
  160.   end
  161.   /* HELP LIST*/
  162.   when (translate(args) = "LIST") then do
  163.     str = getExtMsg("helpList")
  164.     /* now collect INF files on the bookshelf */
  165.     shelf = value('BOOKSHELF',, 'OS2ENVIRONMENT')
  166.     j = 0
  167.     do while (shelf \= "")
  168.         parse var shelf shelf2 ";" shelf
  169.         rc = SysFileTree(shelf2"\*.inf", found)
  170.         do i = 0 to found.0
  171.             parse var found.i fdate ftime fsize fattr fpath
  172.             if (fpath \= "") then do
  173.                 fname = lowercase(filespec('NAME', fpath))
  174.                 fname = left(fname, pos(".inf", fname)-1)
  175.                 j = j+1
  176.                 fname.j = fname
  177.             end
  178.         end
  179.     end
  180.  
  181.     /* now check all environment variables */
  182.     localqueue = rxqueue('create')
  183.     oldqueue = rxqueue('set', localqueue)
  184.     'set 2>&1 | rxqueue' localqueue
  185.     do while (queued() > 0)
  186.        parse pull line
  187.        say line
  188.     end /* do */
  189.     call rxqueue 'delete', localqueue
  190.     call rxqueue 'set', oldqueue
  191.  
  192.     /* now prepare output */
  193.     fname.0 = j
  194.     call sort
  195.     do i = 1 to j
  196.         str = str||fname.i" "
  197.     end
  198.     str = str||nl
  199.     call msg str
  200.   end /* when (LIST) */
  201.   when (left(args, 1) = "-") then
  202.     call msg strReplace(getExtMsg("invalidOptionMsg"), '%a', args), "xhelp"
  203.   /* known command, e.g. help dir */
  204.   when (symbol(_upper) = "VAR") then do
  205.     if (value(_upper) \= '') then
  206.         interpret value(_upper)
  207.     else cont = 1
  208.   end /* when */
  209.   otherwise
  210.     cont = 1
  211. end /* select */
  212.  
  213. if (cont=1) then do /* only one argument given */
  214.     /* help cmdref dir */
  215.     if (words(args) = 2) then do
  216.         book = value('HELP.'word(args, 1),,'OS2ENVIRONMENT')
  217.         if (book = "") then book = value(word(args, 1),,'OS2ENVIRONMENT')
  218.         if (pos("+", book) = 0) then book=""
  219.         if (book = "") then book = word(args, 1)
  220.         topic_ = word(args, 2)
  221.         call msg strReplace(strReplace(getExtMsg("bookshelfMsg"), '%a', book), '%b', topic_)
  222.         call startView book topic_
  223.                 /* search given book (arg 1) for given topic (arg 2) */
  224.     end
  225.     else do
  226.       sysmsg = 0
  227.       if (datatype(args) = "NUM") then
  228.           sysmsg = 1
  229.       else
  230.           do while (sysmsgList \= "")
  231.               parse var sysmsgList s_ sysmsgList
  232.               if ( (left(translate(args), length(s_)) = s_) & (datatype(substr(args, length(s_)+1))="NUM"))then /* numeric --> help for system message */
  233.                   sysmsg = 1
  234.           end
  235.       if (sysmsg) then
  236.         "call helpmsg" args    /* "helpmsg" should be in the OS/2 directory; try "helpmsg 2166" */
  237.       else do  /* non-numeric --> more checks nevessary */
  238.           if (pos('+', args) > 0) then do
  239.                                         /* there's a "+" sign --> display several INFs */
  240.             call msg strReplace(getExtMsg("callViewMsg"), '%a', args)
  241.             call startView args
  242.           end
  243.           else do
  244.             book = value('HELP.'args,,'OS2ENVIRONMENT')
  245.             if (book = "") then book = value(args,,'OS2ENVIRONMENT')
  246.             if (pos("+", book) = 0) then book=""
  247.             if (book \= "") then do
  248.                                         /* envir'variable  --> display several INFs */
  249.                 call msg strReplace(getExtMsg("callViewMsg"), '%a', book)
  250.                 call startView book
  251.             end
  252.             else if (stream(args, "c", "query exists") \= "") & (right(args, 4) \= ".inf") then
  253.                 call processExternalFile(args)
  254.             else do
  255.                 loc = SysSearchPath("BOOKSHELF", args)
  256.                 if (loc = "") then loc = SysSearchPath("BOOKSHELF", args||".inf")
  257.                 if (loc \= "") then do     /* argument is an existing INF file --> open it */
  258.                   call msg strReplace(getExtMsg("callViewMsg"), '%a', loc)
  259.                   call startView loc
  260.                 end
  261.                 else do /* otherwise search whole bookshelf for args */
  262.                   topic_ = args
  263.                   call msg strReplace(strReplace(getExtMsg("bookshelfMsg"), '%a', "BOOKSHELF"), '%b', topic_)
  264.                   call startView '/'||topic_  /* cool feature: "view /<topic>" will search bookshelf for <topic>! */
  265.                 end
  266.             end
  267.           end
  268.      end
  269.     end
  270. end /* if */
  271.  
  272. exit
  273.  
  274. halt:
  275.     say ansiReset
  276.     call msg getExtMsg("abortMsg"), "xhelp"
  277. exit
  278.  
  279. strReplace: procedure
  280.     /* syntax: result = strReplace(str, old, new) */
  281.     /* will replace a by b in oldstr */
  282.     parse arg str, old, new
  283.     p = pos(old, str)
  284.     if (p > 0) then
  285.         str = left(str, p-1)||new||substr(str,p+length(old))
  286.     drop p
  287. return str
  288.  
  289. lowercase: procedure
  290.     return translate(arg(1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  291.  
  292. startView: procedure
  293.     parse arg args
  294.     if (sysSearchPath('PATH', 'VIEW.EXE') \= "") then
  295.         'start view' args
  296.     else call msg getExtMsg("noViewMsg")
  297. return
  298.  
  299. sort:  procedure expose fname.
  300.    M = 1
  301.    do while (9 * M + 4) < fname.0
  302.       M = M * 3 + 1
  303.    end /* do while */
  304.                         /* sort fname                                  */
  305.    do while M > 0
  306.       K = fname.0 - M
  307.       do J = 1 to K
  308.          Q = J
  309.          do while Q > 0
  310.             L = Q + M
  311.             if translate(fname.Q) <<= translate(fname.L) then
  312.               leave
  313.                         /* switch elements                            */
  314.             tmp      = fname.Q
  315.             fname.Q = fname.L
  316.             fname.L = tmp
  317.             Q = Q - M
  318.          end /* do while Q > 0 */
  319.       end /* do J = 1 to K */
  320.       M = M % 3
  321.    end /* while M > 0 */
  322. return
  323.  
  324. sayBreak:
  325.     call charout , ansiReset
  326.     if (arg(1) = "") then do
  327.         call charout , '0d0a'x||copies(" ",indent.level_)
  328.         xpos = indent.level_
  329.     end
  330.     else do
  331.         call charout , '0d0a'x||copies(" ",arg(1))
  332.         xpos = arg(1)
  333.     end
  334.     call setColors
  335.     lastChar = " "
  336. return
  337.  
  338. sayChar: procedure expose lastChar xpos
  339.     call charout , arg(1)
  340.     lastChar = arg(1)
  341.     xpos = xpos+length(arg(1))
  342. return
  343.  
  344. setColors:
  345.     call charout , ansiReset
  346.     if (anchor) then
  347.         call charout , ansiAnchorOn
  348.     if (bold) then
  349.         call charout , ansiBoldOn
  350.     if (italics) then
  351.         call charout , ansiItalicsOn
  352. return
  353.  
  354. HTMLerror:
  355.     l_ = sigl
  356.     say "HTML error in line" l_":"
  357.     say sourceline(l_)
  358.     exit
  359.  
  360. oldRexxUtils:
  361.     codepage=437
  362. signal weiter
  363.  
  364. sayHTML: /* Syntax: sayHTML <htmlstr>)*/
  365.     signal on novalue name HTMLerror
  366.  
  367.     signal on syntax name oldRexxUtils
  368.     codepage = SysQueryProcessCodePage()
  369.     weiter:
  370.     signal off failure
  371.  
  372.     call charout , getExtMsg("formattingMsg")"..."
  373.     txt = arg(1)||" "||'00'x
  374.         /* a little cheat for making word break in the last line work*/
  375.     do while (pos('0d0a'x, txt) > 0)
  376.         txt = strReplace(txt, '0d0a'x, '00'x)
  377.     end
  378.     call charout , "."
  379.     do while (pos('0d'x, txt) > 0)
  380.         txt = strReplace(txt, '0d'x, '00'x)
  381.     end
  382.     call charout , "."
  383.     do while (pos('0a'x, txt) > 0)
  384.         txt = strReplace(txt, '0a'x, '00'x)
  385.     end
  386.     call charout , "."
  387. /*    do while (pos("      ", txt) > 0)
  388.         txt = strReplace(txt, "      ", ' ')
  389.     end
  390.     call charout , "."
  391.     do while (pos("  ", txt) > 0)
  392.         txt = strReplace(txt, "  ", ' ')
  393.     end*/
  394.  
  395.     parse value SysTextScreenSize() with row col
  396.     scrwidth = col-2
  397.     lastchar = ""
  398.  
  399.     anchor = 0
  400.     bold = 0
  401.     italics = 0
  402.  
  403.     xpos = 0
  404.     level_ = 1
  405.     indent.level_ = 0
  406.     indentFirst.level_ = 0
  407.  
  408.     call charout, '0d0a1b'x||'[1A'||'1b'x||'[K'
  409.     call setColors
  410.     /* now go through the whole text on a per-character basis */
  411.     do p1 = 1 to length(txt)
  412.       ch = substr(txt, p1, 1)
  413.  
  414.       select
  415.         when (ch = "<") then do
  416.             /* HTML tag found */
  417.             p2 = pos('>', txt, p1)
  418.             tag = substr(txt, p1+1, p2-p1-1)
  419.             parse upper var tag cmd args
  420.             select
  421.                 when cmd = "!--" then do /* comment: skip following */
  422.                     p1 = pos("-->", txt, p1)+2 /* p1 will be set to p2 later on */
  423.                     iterate
  424.                 end
  425.                 when cmd = "HEAD" then do /* comment: skip following */
  426.                     p1 = pos("/HEAD>", translate(txt), p1)+5 /* p1 will be set to p2 later on */
  427.                     iterate
  428.                 end
  429.                 when (cmd = "BR") | (cmd = "TR") then
  430.                     call sayBreak
  431.                 when (cmd = "HR") then do
  432.                     call sayBreak
  433.                     call sayChar " "copies("─", scrWidth-(indent.level_))
  434.                 end
  435.                 when (cmd = "IMG") then do
  436.                     call sayChar imageString
  437.                     call setColors
  438.                 end
  439.                 when cmd = "P" then do
  440.                     call sayBreak
  441.                     call sayBreak
  442.                 end
  443.                 when (cmd = "A") & (pos("HREF=", translate(args)) > 0) then do
  444.                     anchor = 1
  445.                     call setColors
  446.                 end
  447.                 when cmd = "/A" then do
  448.                     anchor = 0
  449.                     call setColors
  450.                 end
  451.                 when (cmd = "B") then do
  452.                     bold = 1
  453.                     call setColors
  454.                 end
  455.                 when cmd = "/B" then do
  456.                     bold = 0
  457.                     call setColors
  458.                 end
  459.                 when (cmd = "I") then do
  460.                     italics = 1
  461.                     call setColors
  462.                 end
  463.                 when cmd = "/I" then do
  464.                     italics = 0
  465.                     call setColors
  466.                 end
  467.                 when cmd = "UL" then do
  468.                     oldlevel_ = level_
  469.                     level_ = level_+1
  470.                     indent.level_ = (indent.oldlevel_)+3
  471.                     indentFirst.level_ = (indentFirst.oldlevel_)+3
  472.                     do while (args \= "")
  473.                         parse upper var args arg1 args
  474.                         if substr(arg1, 1, 5) = "FIRST" then
  475.                             indentFirst.level_ = substr(arg1, 7)
  476.                         if substr(arg1, 1, 4) = "NEXT" then
  477.                             indent.level_ = substr(arg1, 6)
  478.                     end
  479.                 end
  480.                 when cmd = "/UL" then do
  481.                     oldlevel_ = level_
  482.                     level_ = level_-1
  483.                     if (level_ < 1) then level_ = 1
  484.                     else if (level_=1) then call sayBreak
  485.                 end
  486.                 when cmd = "LI" then do
  487.                     call sayBreak indentFirst.level_
  488.                 end
  489.                 when cmd = "TAB" then do
  490.                     if (xpos < indent.level_) then
  491.                         call sayChar copies(" ", (indent.level_)-xpos)
  492.                     else call sayBreak
  493.                     lastChar = " "
  494.                 end
  495.                 when cmd = "DBG" then
  496.                     say xpos
  497.                 otherwise /* ignore */
  498.             end /* select */
  499.             p1 = p2 /* skip processed characters */
  500.         end
  501.         when (ch = "&") & (substr(txt, p1+1, 1) \= " ") then do
  502.             /* special chars found */
  503.             p2 = pos(';', txt, p1)
  504.             code = substr(txt, p1+1, p2-p1-1)
  505.             p3 = pos(code||"=", escapeList.codepage)
  506.             if p3 > 0 then
  507.                 call sayChar substr(escapeList.codepage, pos("=", escapeList.codepage, p3)+1, 1)
  508.             p1 = p2 /* skip the processed chars */
  509.         end
  510.         when (ch = " ") | (ch = '00'x) then do
  511.                 /* space found: now check if following word still fits in line */
  512.                 charwise = 0
  513.                 p3 = min(pos(' ', txt, p1+1), pos('00'x, txt, p1+1))
  514.                 if (p3-p1-1 > 0) then do
  515.                     wrd = substr(txt, p1+1, p3-p1-1)
  516.                     lw = length(wrd)
  517.  
  518.                     p1_ = 0
  519.                     do forever
  520.                         p1_ = pos("<", wrd, p1_+1)
  521.                         if (p1_ > 0) then do
  522.                             p2_ = pos(">", wrd, p1_+1)
  523.                             lw = lw - (p2_-p1_)-1
  524.                             charwise = 1
  525.                         end
  526.                         else leave
  527.                     end
  528.  
  529.                     p3_ = 0
  530.                     do forever
  531.                         p3_ = pos("&", wrd, p3_+1)
  532.                         if (p3_ > 0) then do
  533.                             p4_ = pos(";", wrd, p3_+1)
  534.                             lw = lw - (p4_-p3_)
  535.                             charwise = 1
  536.                         end
  537.                         else leave
  538.                     end
  539.  
  540.                     /* lw now contains the "real" length of the word w/out tags and such */
  541.  
  542.                     if (xpos+lw > scrwidth) then do
  543.                         if (pos('<UL', wrd) = 0) & (pos('</UL', wrd) = 0) & (pos('<LI>', wrd) = 0) & (pos('<BR>', wrd) = 0) & (pos('<P>', wrd) = 0) then do
  544.                             call sayBreak
  545.                         end
  546.                         charwise = 1
  547.                     end
  548.                     else if (lastChar \= " ") then
  549.                          call sayChar " "
  550.                     if \charwise then do
  551.                          call sayChar wrd
  552.                          p1 = p1+length(wrd)
  553.                     end
  554.                 end /* if */
  555.         end /* when */
  556.         otherwise
  557.                 call sayChar ch
  558.       end /* select */
  559.     end /* do while */
  560.     call charout , nl||'1b'x'[0m'
  561. return
  562.  
  563. processExternalFile:
  564.     filename = arg(1)
  565.     txt = ""
  566.  
  567.     file = stream(filename, "c", "query exists");
  568.     if (file = "") then call charout , SysGetMessage(0002)
  569.     else do
  570.         fileLength = chars( file )
  571.         call stream file, "c", "OPEN READ"
  572.         txt = CharIn( file, 1, fileLength )
  573.         call stream file, "c", "CLOSE"
  574.     end
  575.     if (txt \= "") then
  576.         call msg txt
  577. return
  578.  
  579. extractMsg: procedure /* str = extractMsg(longstr, topic) */
  580.     msgFile = arg(1)
  581.     topic2 = arg(2)
  582.     str3 = "xhelp message file" msgFile "not found."
  583.     msgfile = sysSearchPath("PATH", msgFile)
  584.     if (msgFile \= "") then do
  585.         msgFileLength = chars( msgFile )
  586.         call stream msgFile, "c", "OPEN READ"
  587.         str3 = CharIn( msgFile, 1, msgFileLength )
  588.         call stream msgFile, "c", "CLOSE"
  589.         p1 = pos('<TOPIC NAME="'topic2'"', str3)
  590.         if (p1 > 0) then do
  591.             p2 = pos('>', str3, p1)+1
  592.             p3 = pos('</TOPIC>', str3, p2)
  593.             str3 = substr(str3, p2, (p3-p2))
  594.         end
  595.         else str3 = '0d0a'x'Help topic "'topic2'" not found in 'msgFile'.'||'0d0a'x
  596.     end
  597. return str3
  598.  
  599. getExtMsg:
  600.     msgName = arg(1)
  601.     country = value('HELP.COUNTRY',,'OS2ENVIRONMENT')
  602.     if country = "" then country="001"
  603.     str = extractMsg('XHELP'country'.MSG', msgName)
  604. return str
  605.  
  606. msg:
  607.     call charout , getExtMsg("analyzeMsg")
  608.     parse arg str
  609.     if pos("<HTML>", translate(str)) = 0 then do
  610.         call charout, '0d0a1b'x||'[1A'||'1b'x||'[K'
  611.         call charout , str
  612.     end
  613.     else do
  614.         do while (pos('&version;', str) > 0)
  615.            str = strReplace(str, '&version;', getExtMsg("versionString"))
  616.         end
  617.         cmd = arg(2)
  618.         if (cmd \= "") then
  619.             do while (pos('&cmd;', str) > 0)
  620.                 str = strReplace(str, '&cmd;', cmd)
  621.             end
  622.         call charout, '0d0a1b'x||'[1A'||'1b'x||'[K'
  623.         call sayHTML str
  624.     end
  625. return
  626.  
  627. ansiValue: procedure
  628.   normal = '1b'x'[0m'
  629.  
  630.   bright = 1
  631.   underline = 4
  632.   blink = 5
  633.  
  634.   black = 30
  635.   red = 31
  636.   green = 32
  637.   yellow = 33
  638.   blue = 34
  639.   magenta = 35
  640.   cyan = 36
  641.   white = 37
  642.  
  643.   litcolor = arg(1); ansicolor = ''; on = 0
  644.   do while litcolor \= ''
  645.      parse upper var litcolor item litcolor
  646.      if item = 'ON' then on = 10
  647.      else
  648.        ansicolor = ansicolor || ';' || value(item)+on
  649.   end /* do */
  650.  
  651. return '1b'x'['strip(ansicolor,'L',';')'m'
  652.  
  653.