home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / editor / epmtools / ebooke / bkeys.e < prev    next >
Encoding:
Text File  |  1992-10-13  |  119.9 KB  |  3,446 lines

  1. /*         Tagged-file Support Main Macro               */
  2. /*                                                      */
  3. /* This is the main processing macro for the tagged-    */
  4. /* file syntax support, part of EBOOKIE PACKAGE from    */
  5. /* PCTOOLS.                                             */
  6. /*                                                      */
  7. /* It intercepts the following keys:                    */
  8. /*   tab ....... tab word (variable)                    */
  9. /*   backtab ... backtab word (variable)                */
  10. /*   space ..... check for tag                          */
  11. /*   c_space ... check for tag                          */
  12. /*   c_enter ... check for tag                          */
  13. /*   enter ..... check for tag                          */
  14. /*   up ........ check for tag                          */
  15. /*   down ...... check for tag                          */
  16. /*   pgup ...... check for tag                          */
  17. /*   pgdn ...... check for tag                          */
  18. /*   tag_start . start of tag (configurable)            */
  19. /*   tag_end ... check for tag (configurable)           */
  20. /*   a_1 ....... edit imbed file                        */
  21. /*   a_2 ....... enter remembered tag                   */
  22. /*   a_h ....... get keyword help                       */
  23. /*   c_h ....... view tag reference                     */      /* temple */
  24. /*   a_i ....... index                                  */
  25. /*   and all other keys of the keyboard.                */
  26. /*                                                      */
  27. /* The following commands are supported:                */
  28. /*   bookie .... Force start/stop of tag support        */
  29. /*   bookief ... Define tag-definition files            */
  30. /*   bkmattr ... Insert attibutes (optional)            */
  31. /*   bkmsym .... Replace all chars with symbols (opt.)  */
  32. /*   bkmdebug .. Debugging support (optional)           */
  33. /*                                                      */
  34. /* For the change history refer to EBOOKIE SCRIPT.      */
  35. /*                                                      */
  36.  
  37. /* Check if we are in the main E.E compilation, or      */
  38. /* if the support is compiled separately.               */
  39. compile if not defined(BLACK)
  40.   const bkm_is_external=1
  41.   include 'stdconst.e'
  42.   include 'colors.e'
  43.   tryinclude 'mycnf.e'
  44. compile if not defined(EBOOKIE_ENH)
  45.   const EBOOKIE_ENH = 0
  46. compile endif
  47. compile if EBOOKIE_ENH = 1
  48. ;  include 'EPMGCNF.SMP'
  49. compile if not defined(NLS_LANGUAGE)
  50.   NLS_LANGUAGE = 'ENGLISH'
  51. compile endif
  52. include NLS_LANGUAGE'.e'
  53. compile endif
  54. compile if EPM & EVERSION < '5.16'
  55.   tryinclude 'econfig.e'
  56. compile endif
  57. ;  include 'stdcnf.e'
  58. compile else
  59.   const bkm_is_external=0
  60. compile if not defined(EBOOKIE_ENH)
  61.   const EBOOKIE_ENH = 0
  62. compile endif
  63. compile endif
  64.  
  65. /* First we check the version of the editor. The        */
  66. /* minimum version required are the .12 versions. If    */
  67. /* the user has a wrong version, compiling terminates   */
  68. /* with an error message.                               */
  69. compile if E3
  70.   compile if EVERSION < '3.12'
  71.     *** EBOOKIE: Error, incorrect version of E3, must be at least 3.12.
  72.   compile endif
  73. compile endif
  74.  
  75. compile if EOS2
  76.   compile if EVERSION < '4.12'
  77.     *** EBOOKIE: Error, incorrect version of EOS2, must be at least 4.12.
  78.   compile endif
  79. compile endif
  80.  
  81. compile if EPM
  82.   compile if EVERSION < '5.12'
  83.     *** EBOOKIE: Error, incorrect version of EPM, must be at least 5.12.
  84.   compile endif
  85. compile endif
  86.  
  87. /* First we have to define some constants.              */
  88. CONST
  89.   bkm_version='2.10'
  90.  
  91. /* LAM:  Define these as STDCNF.E would:                */
  92. compile if not defined(ENHANCED_ENTER_KEYS)
  93.    ENHANCED_ENTER_KEYS = 0
  94. compile endif
  95. compile if not defined(ENTER_ACTION)
  96.    ENTER_ACTION   = 'ADDLINE'
  97. compile endif
  98. compile if not defined(EPATH)
  99.  compile if EPM    -- EPM uses a different name, for easier coexistance
  100.    EPATH= 'epmpath'
  101.  compile else
  102.    EPATH= 'epath'
  103.  compile endif
  104. compile endif
  105.  
  106.    ANY_CLASS = 0
  107.    COLOR_CLASS = 1
  108.  
  109. /* Check whether the user wants to replace the colons   */
  110. /* of invalid tags with "&gml." or "&colon" If it is    */
  111. /* zero, the colons are not replaced.                   */
  112. compile if defined(my_bkm_repl_colon)
  113.   bkm_repl_colon=my_bkm_repl_colon
  114. compile else
  115.   bkm_repl_colon=1
  116. compile endif
  117.  
  118. /* The default tag-definition file.                     */
  119. compile if defined(my_bkm_def_file)
  120.   bkm_def_file=my_bkm_def_file
  121. compile else
  122.   bkm_def_file='BKMTAGS.DEF'
  123. compile endif
  124.  
  125. /* Change margins?                                      */
  126. compile if defined(my_bkm_margins)
  127.   bkm_margins=my_bkm_margins
  128. compile else
  129.   bkm_margins='1 70 1'
  130. compile endif
  131.  
  132. /* Define if EBOOKIE is allowed to change the margins when      */
  133. /* switching to a non-ebookie file. Note: this only has an      */
  134. /* effect in E3. '0' means that EBOOKIE is allowed to change    */
  135. /* the margins, '1' means that EBOOKIE will not change the      */
  136. /* margins.                                                     */
  137. compile if defined(my_bkm_dont_touch_margins)
  138.   compile if E3
  139.     bkm_dont_touch_margins=my_bkm_dont_touch_margins
  140.   compile else
  141.     bkm_dont_touch_margins=0
  142.   compile endif
  143. compile else
  144.   bkm_dont_touch_margins=0
  145. compile endif
  146.  
  147. /* Dynamic margins?                                     */
  148. compile if defined(my_bkm_tags_between)
  149.   bkm_tags_between=my_bkm_tags_between
  150. compile else
  151.   bkm_tags_between=''
  152. compile endif
  153. compile if bkm_tags_between <> ''
  154. compile if bkm_dont_touch_margins
  155.     *** EBOOKIE: Error, conflicting options 'my_bkm_tags_between' and 'my_bkm_dont_touch_margins'.
  156. compile endif
  157. compile endif
  158.  
  159. /* Debugging?                                           */
  160. compile if defined(my_bkm_debugging)
  161.   bkm_debugging=my_bkm_debugging
  162. compile else
  163. compile if bkm_is_external
  164.   bkm_debugging=1            -- include debugging if externally linked
  165. compile else
  166.   bkm_debugging=0            -- save space, don't include debugging
  167. compile endif
  168. compile endif
  169.  
  170. /* Define the page-up routine                           */
  171. compile if defined(my_bkm_page_up)
  172.   bkm_page_up=my_bkm_page_up
  173. compile else
  174.   bkm_page_up=0
  175. compile endif
  176.  
  177. /* Define the page-down routine                         */
  178. compile if defined(my_bkm_page_down)
  179.   bkm_page_down=my_bkm_page_down
  180. compile else
  181.   bkm_page_down=0
  182. compile endif
  183.  
  184. /* Define the line-up routine                           */
  185. compile if defined(my_bkm_line_up)
  186.   bkm_line_up=my_bkm_line_up
  187. compile else
  188.   bkm_line_up=0
  189. compile endif
  190.  
  191. /* Define the line-down routine                         */
  192. compile if defined(my_bkm_line_down)
  193.   bkm_line_down=my_bkm_line_down
  194. compile else
  195.   bkm_line_down=0
  196. compile endif
  197.  
  198. /* Define the enter-key routine                         */
  199. compile if defined(my_bkm_enter)
  200.   bkm_enter=my_bkm_enter
  201. compile else
  202.   bkm_enter=0
  203. compile endif
  204.  
  205. /* Define if we want to replace special keys with the   */
  206. /* appropriate BookMaster symbols.                      */
  207. compile if defined(my_bkm_want_symbols)
  208.   bkm_want_symbols=my_bkm_want_symbols
  209. compile else
  210.   bkm_want_symbols=1
  211. compile endif
  212.  
  213. compile if bkm_want_symbols
  214.   compile if defined(my_bkm_codepage)
  215.     bkm_cdpg=my_bkm_codepage
  216.   compile else
  217.     bkm_cdpg='437'
  218.   compile endif
  219. compile endif
  220.  
  221. /* Define the number of lines searched when no footprint*/
  222. /* is found, or the extension does not indicate a tagged*/
  223. /* file.                                                */
  224. compile if defined(my_bkm_search)
  225.   bkm_search=my_bkm_search
  226. compile else
  227.   bkm_search=0
  228. compile endif
  229.  
  230. /* Define the file extensions for which you want the support to */
  231. /* be started automatically. If you set this constant to blank  */
  232. /* the file extension is not used to determine the file type.   */
  233. compile if defined(my_bkm_files)
  234.   bkm_files=my_bkm_files
  235. compile else
  236.   bkm_files='SCR BKM SCT FOI IPF SCRIPT STYLE'
  237. compile endif
  238.  
  239. /* Define which definition is to be used with a specific extenstion */
  240. compile if defined(my_bkm_ext_def)
  241.   bkm_ext_def=my_bkm_ext_def
  242. compile else
  243.   bkm_ext_def=''
  244. compile endif
  245.  
  246. /* Define the parameter expansion. "ALL" means that the space   */
  247. /* key always expands all parameters, "USUAL" (which is the     */
  248. /* default) expands only the usual parameters (c-enter or       */
  249. /* c-space then expands all parameters).                        */
  250. compile if defined(my_bkm_space_key)
  251.   bkm_space_key=my_bkm_space_key
  252. compile else
  253.   bkm_space_key='USUAL'
  254. compile endif
  255.  
  256. /* Define the attribute support. This is only available in EPM  */
  257. compile if EVERSION > '5.15'
  258. compile if defined(my_bkm_attr)
  259.   bkm_attr=my_bkm_attr
  260. compile if defined(my_bkm_attr_colors)
  261.   bkm_attr_colors=my_bkm_attr_colors
  262. compile else
  263.   bkm_attr_colors=223  -- White + Light_MagentaB
  264. compile endif
  265. compile if defined(my_bkm_attr_init)
  266.   bkm_attr_init=my_bkm_attr_init
  267. compile else
  268.   bkm_attr_init=0
  269. compile endif
  270. compile else  -- else not defined(my_bkm_attr)
  271.   bkm_attr=0
  272. compile endif
  273. compile else  -- else EVERSION <= 5.15
  274.   bkm_attr=0
  275. compile endif
  276.  
  277. /* Define the index support. */
  278. compile if defined(my_bkm_idx_supp)
  279.   bkm_idx_supp=my_bkm_idx_supp
  280. compile else
  281.   bkm_idx_supp=1
  282. compile endif
  283.  
  284. compile if bkm_idx_supp
  285.   compile if defined(my_bkm_keep_index_cases)
  286.     bkm_keep_index_cases=my_bkm_keep_index_cases
  287.   compile else
  288.     bkm_keep_index_cases=0
  289.   compile endif
  290. compile endif
  291.  
  292. /* Define the help support. */
  293. compile if defined(my_bkm_help_support)
  294.   bkm_help_support=my_bkm_help_support
  295. compile else
  296.   bkm_help_support=1
  297. compile endif
  298.  
  299. /* Define the help support. */               /* temple */
  300. compile if defined(my_bkm_help_reference)
  301.   compile if EPM
  302.     bkm_help_reference=my_bkm_help_reference
  303.   compile else
  304.     bkm_help_reference=0                    /* NO in DOS mode */
  305.   compile endif
  306. compile else
  307.   compile if EPM
  308.     bkm_help_reference=1                    /* Only in EPM */
  309.   compile else
  310.     bkm_help_reference=0                    /* otherwise no */
  311.   compile endif
  312. compile endif
  313.  
  314. compile if not defined(KEEP_HELP_AT_RIGHT)
  315.    KEEP_HELP_AT_RIGHT = 1   -- Ensure that the Help menu is rightmost
  316. compile endif
  317.  
  318. compile if not defined(TILDE_CHAR)
  319.  compile if EVERSION < '5.21'
  320.    TILDE_CHAR = ''
  321.  compile else
  322.    TILDE_CHAR = '~'
  323.  compile endif
  324. compile endif
  325.  
  326. /* The DEFINIT routine is called when the editor is     */
  327. /* started. First we define some global variables.      */
  328. definit
  329.   universal bkm_def
  330.   universal bkm_idx
  331.   universal bkm_avail
  332. compile if bkm_tags_between<>''
  333.   universal bkm_between
  334.   universal bkm_between_new
  335. compile endif
  336. compile if bkm_debugging
  337.   universal bkm_debug
  338. compile endif
  339.   universal bkm_nocheck
  340.   universal bkm_save_file
  341.   universal bkm_last_colon
  342.   universal bkm_last_colon_line
  343.   universal bkm_num
  344.   universal bkm_cur_num
  345.   universal bkm_rep_tag
  346.   universal bkm_config
  347. compile if bkm_want_symbols
  348.   universal bkm_symbols
  349.   universal bkm_sym_file
  350.   universal bkm_codepage
  351. compile endif
  352.   universal bkm_tag_start
  353.   universal bkm_tag_end
  354.   universal bkm_end_tag
  355.   universal bkm_inv_tag_rep
  356.   universal bkm_temp_path
  357.   universal bkm_keepspace
  358. compile if EPM
  359.   universal bkm_did_menu
  360.   universal defaultmenu
  361.   universal activemenu
  362.  compile if EVERSION >= 5.20
  363.    universal activeaccel
  364.  compile endif
  365.  
  366.   link_rc = rc
  367. compile endif
  368.  
  369. ; LAM:  Would be both shorter and faster to convert this to:
  370. ;  parse value '' with bkm_temp_path bkm_def bkm_config bkm_idx ...
  371.  
  372.   bkm_temp_path=''
  373.   bkm_def=''                    -- internal name of the definition file
  374.   bkm_config = ''
  375.   bkm_idx=''                    -- name of the index
  376.   bkm_avail=-1                  -- flag (-1=not init., 0=unavailable, 1=available)
  377. compile if bkm_tags_between<>''
  378.   bkm_between=''                -- starting tag of margin change construct
  379.   bkm_between_new=''            -- change required?
  380. compile endif
  381. compile if bkm_debugging
  382.   bkm_debug=0                   -- flag (0=no debug, 1=debug on)
  383. compile endif
  384. ; 'echo on'                     -- remove semicolon to get additional trace
  385.   bkm_nocheck=0                 -- flag (1=don't check files in bkm_init)
  386.   bkm_save_file=''              -- current tag definition files
  387.   bkm_last_colon=0              -- position of last colon
  388.   bkm_last_colon_line=0         -- line number of last colon
  389.   bkm_num=1                     -- number of the first/next index and tag-def. file
  390.   bkm_cur_num=0                 -- number of the current index
  391.   bkm_rep_tag=''                -- tag which should be inserted if a_2 is pressed
  392.   bkm_tag_start=''              -- first character of a tag
  393.   bkm_tag_end=''                -- last character of a tag
  394.   bkm_end_tag=''                -- character sequence of end-tags
  395.   bkm_inv_tag_rep=''            -- character sequence replacing the tag-start of invalid tags
  396.   bkm_keepspace = 0             -- initialize
  397. compile if bkm_want_symbols
  398.   bkm_symbols=''                -- symbol table
  399.   bkm_sym_file=''               -- symbol file name
  400.   bkm_codepage=''               -- current codepage
  401. /* Now we try to get the number of the current codepage.*/
  402. compile if E3
  403.   if dos_version()>320 then
  404.     parse value int86x(DOS_INT, 26113, '') with erc acp . scp . . cflag ','
  405.     if not cflag then
  406.       bkm_codepage=strip(acp)
  407.     endif
  408.   else
  409.     bkm_codepage=bkm_cdpg
  410.   endif
  411. compile else
  412.   codepage = '??'; datalen = '??'
  413.   call dynalink('DOSCALLS',            -- dynamic link library name
  414.                 '#130',                -- ordinal value for DOSGetCP
  415.                 atoi(2)            ||  -- length of code page list
  416.                 selector(codepage) ||  -- string selector
  417.                 offset(codepage)   ||  -- string offset
  418.                 selector(datalen)  ||  -- string selector
  419.                 offset(datalen) )      -- string offset
  420.   bkm_codepage = strip(itoa(codepage,10))
  421. compile endif
  422. compile endif
  423.   call bkm_make_bkm()           -- create the ".BKM" hidden file
  424. compile if EPM
  425.   bkm_did_menu = 0
  426.   compile if bkm_is_external = 1
  427.     call bkm_build_menu()
  428.   compile endif
  429.   rc = link_rc  -- LAM:  Avoid link error message problem.
  430. compile if EVERSION > '5.49' & EBOOKIE_ENH = 1
  431.   include 'd:\epm551\load.e'
  432. defselect
  433.   call bkm_defselect()
  434. compile endif -- EVERSION > '5.49' & EBOOKIE_ENH = 1
  435. compile endif -- EPM
  436.  
  437. /* Define a new command. "bookie" turns the tag         */
  438. /* formatting on or off.                                */
  439. defc bookie=
  440.   universal bkm_avail
  441.   universal bkm_last_colon
  442.   universal bkm_cur_num
  443.   universal bkm_save_file
  444. compile if bkm_tags_between<>''
  445.   universal bkm_between
  446.   universal bkm_between_new
  447. compile endif
  448. compile if bkm_want_symbols
  449.   universal bkm_sym_file
  450. compile endif
  451.   if bkm_avail=0 then
  452.     call bkm_say("No tag-definition file active.",0)
  453.   else
  454.     parm=strip(lowcase(arg(1)))
  455.     if parm='' then parm='on' endif
  456.     if substr(parm,1,2)='of' then
  457. compile if bkm_tags_between<>''
  458.       bkm_between=''
  459.       bkm_between_new=''
  460. compile endif
  461.       bkm_last_colon=0
  462. compile if bkm_want_symbols
  463.       bkm_sym_file=''
  464. compile endif
  465.       call bkm_upd_files(0,' ')
  466.       call bkm_select()
  467.       keys edit_keys
  468.     elseif parm='on' then
  469.       if bkm_avail=-1 then call bkm_chg_def_file(bkm_def_file,0) endif
  470.       if bkm_avail=1 then
  471.         bkm_last_colon=0
  472. compile if E3
  473.         call bkm_chg_def_file(bkm_save_file,0)
  474.         call bkm_upd_files(bkm_cur_num,' ')
  475.         call bkm_upd_line_one()
  476.         call bkm_select()
  477. compile else
  478.         call bkm_upd_line_one()
  479.         call bkm_init()
  480.         keys bkm_keys
  481. compile endif
  482.       endif
  483.     else
  484.      call bkm_say("Invalid parameter" arg(1) "supplied, must be 'ON' or 'OFf'.",0)
  485.     endif
  486.   endif
  487.  
  488. /* Define the "bookief" command to switch to different  */
  489. /* tag-definition file(s)                               */
  490. defc bookief=
  491.   universal bkm_cur_num
  492.   universal bkm_rep_tag
  493.   if arg(1)='' then
  494.     call bkm_say("Required parameter 'filename' omitted.",0)
  495.   else
  496.     call bkm_chg_def_file(arg(1),0)
  497.     call bkm_upd_line_one()
  498.     call bkm_upd_files(bkm_cur_num,' ')
  499.     call bkm_select()
  500.   endif
  501.  
  502. compile if bkm_attr
  503. defc bkmattr=
  504.   call bkm_add_attr(arg(1))
  505. compile endif
  506.  
  507. compile if bkm_want_symbols
  508. defc bkmsym=
  509.   universal bkm_symbols
  510.   universal bkm_sym_file
  511.   universal bkm_codepage
  512.   universal bkm_tag_start
  513.   universal bkm_tag_end
  514.   universal bkm_inv_tag_rep
  515.   fline=0
  516.   if bkm_sym_file='' then
  517.     call bkm_say("Symbol support not active.",0)
  518.   else
  519.     getfileid symid,bkm_sym_file    -- get id of symbol file
  520.     if symid='' then
  521.       call bkm_say("Symbol support not active.",0)
  522.     else
  523.       if marktype()=='' then
  524.         if lowcase(arg(1))='all' then
  525.           fline=1
  526.           lline=.last
  527.           type='LINE'
  528.         else
  529.           call bkm_say("No marked line(s), and 'all' parameter not specified.",0)
  530.         endif
  531.       else
  532.         getmark fline, lline, fcol, lcol
  533.         type=marktype()
  534.       endif
  535.       if fline then
  536.         lines_changed=0
  537.         dont_doit=0
  538.         tag_started=0
  539.         for i=fline to lline
  540.           line_changed=0
  541.           sayerror "BKMSYM: Processing line" i"."
  542.           getline line,i
  543.           if type='LINE' then
  544.             fcol=1
  545.             lcol=length(strip(line,'T'))
  546.           endif
  547.           j=fcol-1
  548.           loop
  549.             j=j+1
  550.             if j>lcol then leave endif
  551.             k=substr(line,j,1)
  552.             if bkm_tag_start==k then           -- start of a tag?
  553.               parse value substr(line,j) with tag .
  554.               parse value tag with tag (bkm_tag_end) .
  555.               if length(tag)>1 then
  556.                 tag_line=bkm_find_tag(tag)      -- try again
  557.                 if tag_line=0 then
  558.                   line=substr(line,1,j-1) || bkm_inv_tag_rep || substr(line,j+1)
  559.                   lcol=lcol+length(bkm_inv_tag_rep)-1
  560.                   j=j+length(bkm_inv_tag_rep)-1
  561.                   line_changed=1
  562.                 else
  563.                   tag_started=1
  564.                   if lowcase(tag)=':cgraphic' then
  565.                     dont_doit=1
  566.                   endif
  567.                   if lowcase(tag)=':ecgraphic' then
  568.                     dont_doit=0
  569.                   endif
  570.                 endif
  571.               endif
  572.             elseif bkm_tag_end==k then         -- end of a tag?
  573.               tag_started=0
  574.             else                               -- else check for replacement
  575.               if not dont_doit then
  576.                 if not tag_started then
  577.                   if pos(k,bkm_symbols) then   -- if found continue
  578.                     getline xline,asc(k),symid  -- get the line from the symbol file
  579.                     parse value xline with . k .       -- get the replacement string
  580. ;;                  k=strip(k)                 -- remove leading & trailing blanks (LAM: Parse did that.)
  581.                     line=substr(line,1,j-1) || k || substr(line,j+1)
  582.                     lcol=lcol+length(k)-1
  583.                     j=j+length(k)-1
  584.                     line_changed=1
  585.                   endif
  586.                 endif
  587.               endif
  588.             endif
  589.           endloop
  590.           if line_changed then
  591.             replaceline line,i
  592.             lines_changed=lines_changed+1
  593.           endif
  594.         endfor
  595.         call bkm_say("Processing ended, "lines_changed" lines changed.",0)
  596.       endif
  597.     endif
  598.   endif
  599. compile endif
  600.  
  601. compile if bkm_debugging
  602. /* Define the "bkmdebug" command to ease the debugging  */
  603. defc bkmdebug=
  604.   universal bkm_def
  605.   universal bkm_idx
  606.   universal bkm_avail
  607. compile if bkm_tags_between<>''
  608.   universal bkm_between
  609. compile endif
  610.   universal bkm_debug
  611.   universal bkm_save_file
  612.   universal bkm_num
  613.   universal bkm_cur_num
  614.   universal bkm_rep_tag
  615.   universal bkm_tag_start
  616.   universal bkm_tag_end
  617.   universal bkm_end_tag
  618.   universal bkm_inv_tag_rep
  619.   universal bkm_temp_path
  620.   universal vTEMP_PATH
  621.   universal vAUTOSAVE_PATH
  622. compile if bkm_want_symbols
  623.   universal bkm_symbols
  624.   universal bkm_sym_file
  625.   universal bkm_codepage
  626. compile endif
  627. compile if bkm_attr
  628.   universal bkm_did_bkmattr
  629. compile endif
  630.   xdebug=strip(lowcase(arg(1)))
  631.   if xdebug='on' then
  632.     bkm_debug=1
  633.   elseif substr(xdebug,1,2)='of' then
  634.     bkm_debug=0
  635.     'echo off'
  636.   elseif substr(xdebug,1,1)='t' then
  637.     'echo on'
  638.     bkm_debug=1
  639.   elseif substr(xdebug,1,1)='e' then
  640.     'echo off'
  641.   elseif substr(xdebug,1,1)='d' then
  642.     insertline ".**EBOOKIE**DEBUGGING**INFO**START**",.line+1
  643.     insertline ".* version:" bkm_version", DOS (OS/2) version="dos_version(),.line+2
  644.     insertline ".* def:" bkm_def,.line+3
  645.     insertline ".* idx:" bkm_idx,.line+4
  646.     insertline ".* avail:" bkm_avail,.line+5
  647.     insertline ".* save_file:" bkm_save_file,.line+6
  648.     insertline ".* num:" bkm_num,.line+7
  649.     insertline ".* cur_num:" bkm_cur_num,.line+8
  650.     insertline ".* rep_tag:" strip(bkm_rep_tag),.line+9
  651.     insertline ".* tag_start:" bkm_tag_start,.line+10
  652.     insertline ".* tag_end:" bkm_tag_end,.line+11
  653.     insertline ".* end_tag:" bkm_end_tag,.line+12
  654.     insertline ".* inv_tag_rep:" bkm_inv_tag_rep,.line+13
  655.     insertline ".* Files known to EBOOKIE:",.line+14
  656.     j=15
  657.     getfileid id,'.BKM'
  658.     if id<>'' then
  659.       last=id.last
  660.       for i=1 to last
  661.         getline line,i,id
  662.         if line='' then iterate endif
  663.         if not pos('==',line) then iterate endif
  664.         insertline ".*     "||line,.line+j
  665.         j=j+1
  666.       endfor
  667.     else
  668.       insertline ".*     file .BKM not in ring.",.line+j
  669.       j=j+1
  670.     endif
  671. compile if bkm_want_symbols
  672.     insertline ".* symbols:" bkm_symbols,.line+j
  673.     insertline ".* codepage=" bkm_codepage,.line+j+1
  674.     insertline ".* sym_file=" bkm_sym_file,.line+j+2
  675.     j=j+3
  676. compile endif
  677. compile if bkm_tags_between<>''
  678.     insertline ".* between:" bkm_between,.line+j
  679.     j=j+1
  680. compile endif
  681.     insertline ".* bkm_temp_path=" bkm_temp_path,.line+j
  682.     j=j+1
  683. compile if bkm_attr
  684.     insertline ".* bkm_did_bkmattr=" bkm_did_bkmattr,.line+j
  685.     j=j+1
  686. compile endif
  687.     insertline ".**EBOOKIE**DEBUGGING**INFO**END**",.line+j
  688.   else
  689.     call bkm_say("Invalid parameter" arg(1) "supplied, must be 'ON|OFf|Display|Trace|Etrace'.",0)
  690.   endif
  691. compile else
  692. defc bkmdebug=
  693.   call bkm_say("Debugging not configured.",0)
  694. compile endif
  695.  
  696. defc bkmimbed=
  697.   call bkm_imbed()
  698.  
  699. defc bkmrem=
  700.   call bkm_rem()
  701.  
  702. compile if bkm_help_support
  703. defc bkmhelp=
  704.   call bkm_help(arg(1))
  705. compile endif
  706.  
  707. compile if bkm_idx_supp
  708. defc bkmidx=
  709.   call bkm_idx_make()
  710. compile endif
  711.  
  712. /* Define the keyset. It redefines the following keys:  */
  713. /*   tab ....... tab word                               */
  714. /*   backtab ... backtab word                           */
  715. /*   space ..... check for bkm tag                      */
  716. /*   enter ..... check for bkm tag                      */
  717. /*   period .... check for bkm tag                      */
  718. /*   colon ..... start of bkm tag                       */
  719. /*   up ........ same as period                         */
  720. /*   down ...... same as period                         */
  721. /*   pgup ...... same as period                         */
  722. /*   pgdown .... same as period                         */
  723. /*   a_1 ....... edit imbed file                        */
  724. /*   a_2 ....... insert default tag                     */
  725. /*   a_h ....... help for tag or attribute              */
  726. /*   c_h ....... view reference for tag                 */    /* temple */
  727. /*   a_i ....... index                                  */
  728. compile if E3
  729. defkeys bkm_keys overlay
  730. compile else
  731. defkeys bkm_keys overlay clear
  732. compile endif
  733.  
  734. /* Define the tabulators to tab one word at the time,   */
  735. /* or use regular tabs.                                 */
  736. def tab=
  737. compile if bkm_tags_between<>''
  738.   universal bkm_between
  739.   if bkm_between='' then                -- if in regular text
  740. compile endif
  741.     getline line                        -- get the current line
  742.     line=strip(line,'T')                -- clean trailing spaces
  743.     line=Substr(line,.col+1)            -- get stuff right of the cursor
  744.     if line<>' ' then                   -- not empty?
  745.       tab_word                          -- jump to next word
  746.     else
  747.       tab                               -- go to next tabstop
  748.     endif
  749. compile if bkm_tags_between<>''
  750.   else                                  -- within example?
  751.     tab                                 -- use regular tabs
  752.   endif
  753. compile endif
  754.  
  755. def s_tab=
  756. compile if bkm_tags_between<>''
  757.   universal bkm_between
  758.   if bkm_between='' then                -- if in regular text
  759. compile endif
  760.     getline line                        -- get the current line
  761.     line=strip(line,'T')                -- clean trailing spaces
  762.     line=Substr(line,.col+1)            -- get stuff right of the cursor
  763.     if line<>' ' then                   -- not empty?
  764.       backtab_word                      -- jump back one word
  765.     else
  766.       backtab                           -- use regular tabstop
  767.     endif
  768. compile if bkm_tags_between<>''
  769.   else                                  -- within example?
  770.     backtab                             -- use regular tabs
  771.   endif
  772. compile endif
  773.  
  774. def pgup=
  775.   universal expand_on
  776.   universal bkm_last_colon
  777.   universal bkm_tag_end
  778.   if bkm_last_colon & expand_on then            -- anything to do?
  779.     if not bkm_expansion(bkm_tag_end) then      -- check for tag
  780. compile if bkm_tags_between<>''
  781.       call bkm_pgup()                           -- no tag, page up
  782. compile else
  783. compile if bkm_page_up=1
  784.       call my_page_up()                         -- call user exit
  785. compile else
  786.       page_up                                   -- do regular page up
  787. compile endif
  788. compile endif
  789.     endif
  790.   else                                          -- nothing to do
  791. compile if bkm_tags_between<>''
  792.     call bkm_pgup()                             -- page up
  793. compile else
  794. compile if bkm_page_up=1
  795.     call my_page_up()                           -- call user exit
  796. compile else
  797.     page_up                                     -- regular page up
  798. compile endif
  799. compile endif
  800.   endif
  801.   bkm_last_colon=0                              -- reset last colon position
  802.  
  803. def pgdn=
  804.   universal expand_on
  805.   universal bkm_last_colon
  806.   universal bkm_tag_end
  807.   if bkm_last_colon & expand_on then            -- anything to do?
  808.     if not bkm_expansion(bkm_tag_end) then      -- check for tag
  809. compile if bkm_tags_between<>''
  810.       call bkm_pgdn()                           -- no tag, page down
  811. compile else
  812. compile if bkm_page_down=1
  813.       call my_page_down()                       -- call user exit
  814. compile else
  815.       page_down                                 -- do regular page down
  816. compile endif
  817. compile endif
  818.     endif
  819.   else                                          -- nothing to do
  820. compile if bkm_tags_between<>''
  821.     call bkm_pgdn()                             -- page down
  822. compile else
  823. compile if bkm_page_down=1
  824.     call my_page_down()                         -- call user exit
  825. compile else
  826.     page_down                                   -- regular page down
  827. compile endif
  828. compile endif
  829.   endif
  830.   bkm_last_colon=0                              -- reset last colon position
  831.  
  832. def up=
  833.   universal expand_on
  834.   universal bkm_last_colon
  835.   universal bkm_tag_end
  836. compile if bkm_tags_between<>''
  837.   universal bkm_between_new
  838.   universal bkm_between
  839. compile endif
  840.   if bkm_last_colon & expand_on then            -- anything to do?
  841.     if not bkm_expansion(bkm_tag_end) then      -- check for tag
  842. compile if bkm_tags_between<>''
  843.       call bkm_up()                             -- no tag, line up
  844. compile endif
  845. compile if bkm_line_up=1
  846.       call my_up()                              -- call user exit
  847. compile else
  848.       up                                        -- do regular line up
  849. compile endif
  850.     endif
  851.   else                                          -- nothing to do
  852. compile if bkm_tags_between<>''
  853.     call bkm_up()                               -- line up
  854. compile endif
  855. compile if bkm_line_up=1
  856.     call my_up()                                -- call user exit
  857. compile else
  858.     up                                          -- regular line up
  859. compile endif
  860.   endif
  861. compile if bkm_tags_between<>''
  862.   if bkm_between<>bkm_between_new then call bkm_upd_files(-1,bkm_between_new) endif
  863. compile endif
  864.   bkm_last_colon=0                              -- reset last colon position
  865.  
  866. def down=
  867.   universal expand_on
  868.   universal bkm_last_colon
  869.   universal bkm_tag_end
  870. compile if bkm_tags_between<>''
  871.   universal bkm_between_new
  872.   universal bkm_between
  873. compile endif
  874.   if bkm_last_colon & expand_on then            -- anything to do?
  875.     if not bkm_expansion(bkm_tag_end) then      -- check for tag
  876. compile if bkm_tags_between<>''
  877.       call bkm_down()                           -- no tag, line down
  878. compile endif
  879. compile if bkm_line_down=1
  880.       call my_down()                            -- call user exit
  881. compile else
  882.       down                                      -- do regular line down
  883. compile endif
  884.     endif
  885.   else                                          -- nothing to do
  886. compile if bkm_tags_between<>''
  887.     call bkm_down()                             -- line down
  888. compile endif
  889. compile if bkm_line_down=1
  890.     call my_down()                              -- call user exit
  891. compile else
  892.     down                                        -- regular line down
  893. compile endif
  894.   endif
  895. compile if bkm_tags_between<>''
  896.   if bkm_between<>bkm_between_new then call bkm_upd_files(-1,bkm_between_new) endif
  897. compile endif
  898.   bkm_last_colon=0                              -- reset last colon position
  899.  
  900. /* Define the space bar. Is it the end of a tag?        */
  901. compile if EVERSION >= 5
  902. def space=
  903. compile else
  904. def ' '=
  905. compile endif
  906.   universal expand_on
  907.   universal bkm_last_colon
  908. compile if bkm_attr
  909.   universal bkm_did_bkmattr
  910. compile endif
  911.   if bkm_last_colon & expand_on then    -- something to do?
  912.     if not bkm_expansion(' ') then      -- check for tag
  913. compile if bkm_attr & EVERSION = '5.19'
  914.     if not insert_state() then delete_char endif
  915. compile endif
  916.       keyin ' '                         -- if none, type space
  917.     endif
  918.   else
  919. compile if bkm_attr & EVERSION = '5.19'
  920.     if not insert_state() then delete_char endif
  921. compile endif
  922. compile if bkm_attr & EVERSION >= '5.50'
  923.     if insert_state() & bkm_did_bkmattr then
  924.        offst = -1
  925.        query_attribute class, val, IsPush, offst, .col, .line
  926.        if class then
  927.           oldlevel = .levelofattributesupport
  928.           .levelofattributesupport = 3
  929.           call to_offset_zero()
  930.        endif
  931.     else
  932.        class = 0
  933.     endif
  934. compile endif
  935.     keyin ' '                           -- type space
  936. compile if bkm_attr & EVERSION >= '5.50'
  937.     if insert_state() & bkm_did_bkmattr & class then
  938.       .levelofattributesupport = oldlevel
  939.     endif
  940. compile endif
  941.   endif
  942.   bkm_last_colon=0                      -- reset last colon position
  943.  
  944. /* Define the c_space (or c_enter) key to display all   */
  945. /* optional parameters.                                 */
  946. compile if EPM
  947. def c_space=
  948. compile else
  949. def c_enter=
  950. compile endif
  951.   universal expand_on
  952.   universal bkm_last_colon
  953.   if bkm_last_colon & expand_on then    -- something to do?
  954.     if not bkm_expansion('a') then      -- check for tag
  955. compile if EPM
  956. compile if bkm_attr & EVERSION = '5.19'
  957.     if not insert_state() then delete_char endif
  958. compile endif
  959.       keyin ' '                         -- type regular space
  960. compile else
  961.       call my_c_enter()                 -- call default routine
  962. compile endif
  963.     endif
  964.   else
  965. compile if EPM
  966. compile if bkm_attr & EVERSION = '5.19'
  967.     if not insert_state() then delete_char endif
  968. compile endif
  969.     keyin ' '                           -- type space
  970. compile else
  971.     call my_c_enter()                   -- call default routine
  972. compile endif
  973.   endif
  974.   bkm_last_colon=0                      -- reset last colon position
  975.  
  976. /* Check the enter key. It might be a regular "enter"   */
  977. /* but it might also be the end of a tag.               */
  978. def enter=
  979.   universal expand_on
  980.   universal bkm_last_colon
  981. compile if ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  982.   universal enterkey
  983. compile endif
  984.   if bkm_last_colon & expand_on then            -- something to do?
  985.     if not bkm_expansion(bkm_tag_end) then      -- check for tag
  986. compile if bkm_enter
  987.       call my_enter_key()               -- call user exit
  988. compile elseif ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  989.       call enter_common(enterkey)
  990. compile else
  991.       call my_enter()                   -- call default routine
  992. compile endif
  993. compile if E3
  994.     else
  995.       call maybe_autosave()             -- check for autosave
  996. compile endif
  997.     endif
  998.   else
  999. compile if bkm_enter
  1000.     call my_enter_key()                 -- call user exit
  1001. compile elseif ENHANCED_ENTER_KEYS & ENTER_ACTION <> ''
  1002.       call enter_common(enterkey)
  1003. compile else
  1004.     call my_enter()                     -- call default routine
  1005. compile endif
  1006.   endif
  1007.   bkm_last_colon=0                      -- reset last colon position
  1008.  
  1009. def a_1=
  1010.   call bkm_imbed()
  1011.  
  1012. def a_2=
  1013.   call bkm_rem()
  1014.  
  1015. compile if bkm_help_support
  1016. def a_h=
  1017.   call bkm_help('a')
  1018.  
  1019. def c_h=
  1020.   call bkm_help('c')
  1021. compile endif
  1022.  
  1023. compile if bkm_idx_supp
  1024.   def a_i=
  1025.   call bkm_idx_make()
  1026. compile endif
  1027.  
  1028. compile if E3
  1029. def '!' - 'â– ' =
  1030. compile else
  1031. def otherkeys
  1032. compile endif
  1033. compile if bkm_want_symbols
  1034.   universal bkm_symbols
  1035.   universal bkm_sym_file
  1036. compile endif
  1037.   universal bkm_last_colon
  1038.   universal bkm_last_colon_line
  1039.   universal expand_on
  1040.   universal bkm_tag_start
  1041.   universal bkm_tag_end
  1042.   universal bkm_end_tag
  1043.   universal bkm_keepspace
  1044. compile if bkm_attr
  1045.   universal bkm_did_bkmattr
  1046. compile endif
  1047.   k=lastkey()                           -- get the last typed character
  1048. compile if EVERSION > 4
  1049.   if length(k)=1 then                   -- regular key?
  1050. compile endif
  1051. compile if EVERSION < 5
  1052.     if not command_state() then         -- check for command line
  1053. compile endif
  1054.       if bkm_tag_start==k then           -- start of a tag?
  1055.         bkm_last_colon=.col             -- yes, save position
  1056.         bkm_last_colon_line=.line       -- and save the line number
  1057.       elseif bkm_tag_end==k then         -- end of a tag?
  1058.         if bkm_last_colon & expand_on then    -- do we have to do something?
  1059.           bkm_keepspace = 0
  1060.           if bkm_expansion(bkm_tag_end) then k='' endif -- expand it
  1061.         endif
  1062.         bkm_last_colon=0                -- reset last tag-start postition
  1063.       elseif k==',' then                -- end of a tag?
  1064.         if bkm_last_colon & expand_on then    -- do we have to do something?
  1065.           bkm_keepspace = 1
  1066.           if bkm_expansion(bkm_tag_end) then k='' endif -- expand it
  1067.         endif
  1068.         bkm_last_colon=0                -- reset last tag-start postition
  1069. compile if bkm_want_symbols
  1070.       else                              -- else check for replacement
  1071.         if bkm_sym_file<>'' then        -- symbol support active?
  1072.           if pos(k,bkm_symbols) then    -- if found key in table continue
  1073.             getfileid id,bkm_sym_file   -- get id of symbol file
  1074.             if id<>'' then              -- if available
  1075.               getline line,asc(k),id    -- get the line from the symbol file
  1076.               parse value line with . k .       -- get the replacement string
  1077.             endif
  1078.           endif
  1079.         endif
  1080. compile endif
  1081.       endif
  1082. compile if EVERSION < 5
  1083.     endif
  1084. compile endif
  1085. compile if bkm_attr & EVERSION >= '5.16' & EVERSION <= '5.19'
  1086.     if not insert_state() then delete_char endif
  1087. compile endif
  1088. compile if bkm_attr & EVERSION >= '5.50'
  1089.     if insert_state() & bkm_did_bkmattr then
  1090.        offst = -1
  1091.        query_attribute class, val, IsPush, offst, .col, .line
  1092.        if class then
  1093.           oldlevel = .levelofattributesupport
  1094.           .levelofattributesupport = 3
  1095.           call to_offset_zero()
  1096.        endif
  1097.     else
  1098.        class = 0
  1099.     endif
  1100. compile endif
  1101.     keyin k
  1102. compile if bkm_attr & EVERSION >= '5.50'
  1103.     if insert_state() & bkm_did_bkmattr & class then
  1104.       .levelofattributesupport = oldlevel
  1105.     endif
  1106. compile endif
  1107. compile if EVERSION > 4
  1108.   endif
  1109. compile endif
  1110.  
  1111. compile if E3
  1112. tryinclude 'mykeys.bkm'
  1113. compile endif
  1114.  
  1115. compile if bkm_enter or bkm_page_up or bkm_page_down or bkm_line_up or bkm_line_down
  1116.   tryinclude 'mybkmkey.e'               -- include user exit routines
  1117. compile endif
  1118.  
  1119. /* The next routines are included only if the dynamic   */
  1120. /* margins feature is selected.                         */
  1121.  
  1122. compile if bkm_tags_between<>''
  1123. /* Process the page up key                              */
  1124. defproc bkm_pgup()
  1125.   universal bkm_between_new
  1126.   universal bkm_between
  1127.   fline=.line                           -- get the current line
  1128. compile if bkm_page_up=1
  1129.   call my_page_up()                     -- call user exit
  1130. compile else
  1131.   page_up                               -- do regular page up
  1132. compile endif
  1133.   lline=.line                           -- save new line number
  1134.   for i=fline to lline by -1            -- loop over all lines skipped
  1135.     i                                   -- set current line
  1136.     call bkm_up()                       -- do a line-up
  1137.   endfor
  1138.   if bkm_between<>bkm_between_new then call bkm_upd_files(-1,bkm_between_new) endif
  1139.  
  1140. /* Process the page down key                            */
  1141. defproc bkm_pgdn()
  1142.   universal bkm_between_new
  1143.   universal bkm_between
  1144.   fline=.line                           -- get the current line
  1145. compile if bkm_page_down=1
  1146.   call my_page_down()                   -- call user exit
  1147. compile else
  1148.   page_down                             -- do regular page down
  1149. compile endif
  1150.   lline=.line                           -- save new line number
  1151.   for i=fline to lline                  -- loop over all lines skipped
  1152.     i                                   -- set current line
  1153.     call bkm_down()                     -- do a line-down
  1154.   endfor
  1155.   if bkm_between<>bkm_between_new then call bkm_upd_files(-1,bkm_between_new) endif
  1156.  
  1157. /* Process the up key.                                  */
  1158. defproc bkm_up()
  1159.   universal bkm_between
  1160.   universal bkm_tag_start
  1161.   universal bkm_tag_end
  1162.   universal bkm_end_tag
  1163. compile if bkm_debugging
  1164.   universal bkm_debug
  1165. compile endif
  1166.   universal bkm_between_new
  1167.   getline line                          -- get the current line
  1168.   parse value line with tag .           -- get the first word of the line
  1169.   if substr(tag,1,1)=bkm_tag_start then -- is the first character a tag-start?
  1170.     parse value tag with tag (bkm_tag_end) .    -- remove the tag-end
  1171.     tag=lowcase(strip(tag))             -- cleanup
  1172.     if bkm_between<>'' then             -- are we between something=
  1173.       if tag=bkm_end_tag||substr(bkm_between,2) | tag=bkm_between then  -- is the current tag an end-tag?
  1174.         'ma' bkm_margins                -- yes, set margins to default
  1175. compile if bkm_debugging
  1176.         if bkm_debug then call bkm_say("Margins changed to" bkm_margins".",0) endif
  1177. compile endif
  1178.         bkm_between_new=''              -- clean flag
  1179.       endif
  1180.     else
  1181.       tag=bkm_tag_start||substr(tag,3)  -- not between something
  1182. compile if EVERSION >= '5.20'
  1183.       if wordpos(tag,bkm_tags_between) then             -- in the list of tags to watch?
  1184. compile else
  1185.       if pos(tag||' ',bkm_tags_between||' ') then       -- in the list of tags to watch?
  1186. compile endif
  1187.         'ma 1 254 1'                    -- yes, reset margins
  1188. compile if bkm_debugging
  1189.         if bkm_debug then call bkm_say("Margins changed to 1 254 1.",0) endif
  1190. compile endif
  1191.         bkm_between_new=tag             -- save current tag
  1192.       endif
  1193.     endif
  1194.   endif
  1195.  
  1196. /* Process the down key                                 */
  1197. defproc bkm_down()
  1198.   universal bkm_between
  1199.   universal bkm_between_new
  1200.   universal bkm_tag_start
  1201.   universal bkm_tag_end
  1202.   universal bkm_end_tag
  1203. compile if bkm_debugging
  1204.   universal bkm_debug
  1205. compile endif
  1206.   getline line                          -- get the current line
  1207.   parse value line with tag .           -- get the first word
  1208.   if substr(tag,1,1)=bkm_tag_start then -- check for tag-start character
  1209.     parse value tag with tag (bkm_tag_end) .    -- remove tag-end
  1210.     tag=lowcase(strip(tag))             -- cleanup
  1211.     if bkm_between<>'' then             -- are we between something?
  1212.       if tag=bkm_end_tag||substr(bkm_between,2) then    -- did we find a tag-end?
  1213.         'ma' bkm_margins                -- set margins to default
  1214. compile if bkm_debugging
  1215.         if bkm_debug then call bkm_say("Margins changed to" bkm_margins".",0) endif
  1216. compile endif
  1217.         bkm_between_new=''              -- set flag
  1218.       endif
  1219.     else                                -- not between something
  1220. compile if EVERSION >= '5.20'
  1221.       if wordpos(tag,bkm_tags_between) then             -- is it in the list?
  1222. compile else
  1223.       if pos(tag||' ',bkm_tags_between||' ') then       -- is it in the list?
  1224. compile endif
  1225.         'ma 1 254 1'                    -- set margins
  1226. compile if bkm_debugging
  1227.         if bkm_debug then call bkm_say("Margins changed to 1 254 1.",0) endif
  1228. compile endif
  1229.         bkm_between_new=tag             -- save tag in flag
  1230.       endif
  1231.     endif
  1232.   endif
  1233.  
  1234. compile endif
  1235.  
  1236. /* The following is the main routine of the macro.        */
  1237. /* We have found a tag. Or better, there was a colon,     */
  1238. /* followed by some undetermined number of other          */
  1239. /* characters, and then a space, a period, or an "enter". */
  1240. defproc bkm_expansion(char)
  1241.   universal bkm_last_colon
  1242.   universal bkm_last_colon_line
  1243.   universal linerest
  1244.   universal bkm_line_text
  1245. compile if bkm_tags_between<>''
  1246.   universal bkm_between
  1247.   universal bkm_between_new
  1248. compile endif
  1249. compile if bkm_debugging
  1250.   universal bkm_debug
  1251. compile endif
  1252.   universal bkm_avail
  1253.   universal bkm_nocheck
  1254.   universal bkm_save_file
  1255.   universal bkm_rep_tag
  1256.   universal bkm_tag_start
  1257.   universal bkm_tag_end
  1258.   universal bkm_end_tag
  1259.   universal bkm_inv_tag_rep
  1260. compile if bkm_want_symbols
  1261.   universal bkm_symbols
  1262.   universal bkm_sym_file
  1263. compile endif
  1264. /* First we have to check if the file should be         */
  1265. /* processed by the macro. If not, we return as fast as */
  1266. /* we can.                                              */
  1267.   if bkm_avail<>1 then return 0 endif           -- If support is inactive, return
  1268.   if bkm_find_file(.filename)<1 then return 0 endif     -- shall we do something?
  1269. compile if bkm_debugging
  1270.   if bkm_debug then call bkm_say("bkm_expansion("char"), bkm="bkm_find_file(.filename)", colon="bkm_last_colon", line="bkm_last_colon_line".",0) endif
  1271. compile endif
  1272. /* It seems that there is work to do. First we get the  */
  1273. /* text of the current line to retrieve the tag.        */
  1274.   retc=1                                        -- set OK return code
  1275. compile if EPM
  1276.   if .line then                                 -- is there a line?
  1277. compile else
  1278.   if .line and (not command_state()) then       -- line? command state?
  1279. compile endif
  1280.     getline line                -- Get the entire line in the variable "line".
  1281.     line=strip(line,'T')        -- Clean up trailing garbage.
  1282.     tag=''                      -- clean current tag
  1283.     linerest=''                 -- clean stuff after tag
  1284.     caution=0                   -- reset flag
  1285. /* First we have to check for the automatic word wrap,  */
  1286. /* which could have moved the tag to the next line. In  */
  1287. /* this case the first word MUST contain a colon at the */
  1288. /* beginning of somewhere in the middle.                */
  1289.     if .line=bkm_last_colon_line+1 then         -- are we in the next line?
  1290.       parse value line with fword .             -- yes, get first word
  1291.       bkm_last_colon=pos(bkm_tag_start,fword)   -- find position of tag in word
  1292.       if not bkm_last_colon then return 0 endif   -- return if no tag-start found
  1293.     endif
  1294. /* When the current column is greater than the column   */
  1295. /* of the colon, it might be a tag.                     */
  1296.     if .col>bkm_last_colon then                 -- cursor right of tag-start?
  1297.       tag=substr(line,bkm_last_colon,.col-bkm_last_colon)       -- get the tag
  1298.       if substr(tag,1,1)<>bkm_tag_start then return 0 endif     -- no tag-start?
  1299.       linerest=substr(line,.col)                -- get stuff to the right
  1300. /* If the tag already contains a colon there must be    */
  1301. /* something wrong. We get the tag, but we have to be   */
  1302. /* careful.                                             */
  1303.       if pos(bkm_tag_end,tag) then            -- tag contains tag-end?
  1304.         tag=substr(tag,1,pos(bkm_tag_end,tag)-1)        -- get tag
  1305.         linerest=substr(line,bkm_last_colon+length(strip(tag))+1) -- get rest
  1306.         caution=2                               -- set caution flag
  1307.       endif
  1308.     else
  1309. /* The cursor is before, or right on the colon. This    */
  1310. /* case has to be treated differently. Probably it is   */
  1311. /* not a tag anyhow, but then we might have to replace  */
  1312. /* the colon with "&gml." or "&colon.".                 */
  1313.       tag=substr(line,bkm_last_colon)           -- get rest of line
  1314.       if substr(tag,1,1)<>bkm_tag_start then return 0 endif     -- exit if no tag
  1315.       parse value tag with tag .                -- get first word of tag
  1316.       caution=1                                 -- set caution flag
  1317.       if pos(bkm_tag_end,tag) then            -- do we have a tag-end too?
  1318.         tag=substr(tag,1,pos(bkm_tag_end,tag)-1)        -- remove it
  1319.         linerest=substr(line,bkm_last_colon+length(strip(tag))+1) -- get new rest
  1320.         caution=2                               -- be careful
  1321.       else
  1322.         linerest=substr(line,bkm_last_colon+length(strip(tag))) -- get rest
  1323.       endif
  1324.     endif
  1325.     if bkm_last_colon>1 then                    -- tag-start not in first col?
  1326.       line=substr(line,1,bkm_last_colon-1)      -- get left stuff
  1327.     else
  1328.       line=''                                   -- no left stuff
  1329.     endif
  1330. /* Now we have got the tag. Put it into lower case and  */
  1331. /* remove the leading and trailing blanks.              */
  1332.     save_tag=strip(tag)                         -- save original cases
  1333.     tag=lowcase(save_tag)                       -- fold to lowercase
  1334. compile if bkm_debugging
  1335.     if bkm_debug then call bkm_say("bkm_expansion... tag="tag" caution="caution" line="line" linerest="linerest,0) endif
  1336. compile endif
  1337. /* If the length of the tag is 1, the user has just     */
  1338. /* typed a colon followed by a space. We leave this     */
  1339. /* as entered.                                          */
  1340.     if length(tag)>1 then                       --
  1341. /* Let's check if there is a valid tag. "tag_line" will */
  1342. /* contain "0" if it is not a valid tag, otherwise it   */
  1343. /* contains the number of the line with the tag. The    */
  1344. /* global variable "bkm_line_text" contains the text of */
  1345. /* the line, which contains the formatting intructions. */
  1346.       tag_line=bkm_find_tag(tag)        -- search tag in index
  1347. /* If the return code was -1 we have found an           */
  1348. /* inconsistency in the index. Now we have to create    */
  1349. /* the index again.                                     */
  1350.       if tag_line=-1 then               -- invalid index found?
  1351.         file=bkm_save_file              -- save all definition file names
  1352.         bkm_save_file=''                -- cleanup
  1353.         call bkm_chg_def_file(file,1)   -- force index generation
  1354.         call bkm_upd_line_one()         -- update line one
  1355.         call bkm_select()               -- activate support
  1356.         tag_line=bkm_find_tag(tag)      -- try again
  1357. /* If the return code again indicates an inconsistency, */
  1358. /* there is nothing left to do except to stop the       */
  1359. /* support. This should never happen.                   */
  1360.         if tag_line=-1 then             -- serious trouble
  1361.           call bkm_say("Unrecoverable error with definition file and index, support halted.",0)
  1362.           bkm_avail=0                   -- deactivate support
  1363.           bkm_nocheck=1                 -- deactivate initialization
  1364.           return 0                      -- exit
  1365.         endif
  1366.       endif
  1367.       if tag_line=0 then                -- did we find the tag?
  1368. /* No, either replace it with variable, or just return. */
  1369. compile if bkm_repl_colon=1
  1370. /* The caution flag is 2 when we found an invalid tag   */
  1371. /* including the tag-end character. The tag-start       */
  1372. /* character will be replaced.                          */
  1373.         if caution=2 then               -- replace it.
  1374.           replaceline line||bkm_inv_tag_rep||substr(save_tag,2)||bkm_tag_end||linerest
  1375.         else            -- otherwise just replace the tag-start character
  1376.           replaceline line||bkm_inv_tag_rep||substr(save_tag,2)||linerest
  1377.         endif
  1378.         if .col>=bkm_last_colon then .col=.col+length(bkm_inv_tag_rep)-1 endif -- set cursor
  1379. compile endif
  1380.         retc=0          -- set bad return code (this is necessary, because the
  1381. ;                       -- last key typed by the user has not been inserted in
  1382. ;                       -- the text yet.
  1383.       else
  1384.         if caution then
  1385.           if linerest<>'' then return 0 endif
  1386.           if caution=2 then return 0 endif
  1387.         endif
  1388. /* The tag has been found. The variable bkm_line_text   */
  1389. /* contains the formatting instructions. The format     */
  1390. /* of this line is:                                     */
  1391. /*                                                      */
  1392. /* :tag   the tag name (without the ending period)      */
  1393. /*                                                      */
  1394. /* flag   the flag. Refer to the routine "bkm_process"  */
  1395. /*        for a description of the flag.                */
  1396. /*                                                      */
  1397. /* text   the required parameters of the tag. The '#'   */
  1398. /*        sign can be used to position the cursor.      */
  1399. /*                                                      */
  1400. /* +      delimiter                                     */
  1401. /*                                                      */
  1402. /* text   the usual optional parameters                 */
  1403. /*                                                      */
  1404. /* +      delimiter                                     */
  1405. /*                                                      */
  1406. /* text   all optional parameters                       */
  1407. /*                                                      */
  1408. /* ||     delimiter                                     */
  1409. /*                                                      */
  1410. /* text   additional lines which should be inserted     */
  1411. /*        after the tag. A "\" is interpreted as "CR"   */
  1412. /*        the "#" can be used to position the cursor.   */
  1413. /*                                                      */
  1414. /* ||     delimiter                                     */
  1415. /*                                                      */
  1416. /* text   lines which should go BEFORE the tag.         */
  1417. /*                                                      */
  1418. /* ||     delimiter                                     */
  1419. /*                                                      */
  1420. /* tag    tag which will be assigned to the a_2 key     */
  1421. /*                                                      */
  1422.         parse value bkm_line_text with xtag flag sameline '||' otherlines '||' beforelines '||' rep_tag
  1423.         if rep_tag<>'' then             -- anything after the third delimiter?
  1424.           bkm_rep_tag=rep_tag           -- assign it to the a_2 key
  1425. compile if bkm_tags_between<>''
  1426.           call bkm_upd_files(-1,bkm_between)    -- save it in hidden file
  1427. compile else
  1428.           call bkm_upd_files(-1,' ')            -- save it in hidden file
  1429. compile endif
  1430.         endif
  1431.         parse value sameline with req '+' opt '+' all   -- get the parameters
  1432. compile if bkm_space_key='ALL'
  1433.         if char=' ' then char='a' endif
  1434. compile endif
  1435.         sameline=strip(req)             -- remove blanks
  1436.         opt=strip(opt)                  -- from optional too
  1437.         all=strip(all)                  -- and finally from optional optional.
  1438.         if char='a' then                -- shall we display everything?
  1439.           char=' '                      -- set to space
  1440.           opt=opt||' '||all             -- optional is all
  1441.         endif
  1442.         if char=' ' then                -- want parameters displayed
  1443. /* Now we have to remove the tag-end character (if any) */
  1444.           if pos(bkm_tag_end,sameline) then sameline=substr(sameline,1,pos(bkm_tag_end,sameline)-1) endif
  1445.           sameline=strip(sameline||' '||opt)    -- store all parms
  1446.         endif
  1447. /* Set the defaults.                                    */
  1448.         if flag='' then flag=1 endif    -- default flag is 1
  1449.         if sameline='' then             -- nothing there?
  1450.           sameline=bkm_tag_end||'#'     -- position cursor after end
  1451.         else
  1452. /* If the first character of the parameter is not an tag-end    */
  1453. /* the we must have a space inserted. (Otherwise the parameters */
  1454. /* would be glued to the tag, and we don't want that, do we?)   */
  1455.           if substr(sameline,1,1)<>bkm_tag_end then sameline=' '||sameline endif
  1456. /* Now we have to add a tag-end character at the end.           */
  1457.           if not pos(bkm_tag_end,sameline) then sameline=sameline||bkm_tag_end endif
  1458. /* If there is no cursor position defined, we put the cursor    */
  1459. /* after the end of the tag.                                    */
  1460.           if not pos('#',sameline) then sameline=sameline||'#' endif
  1461.         endif
  1462. /* Process the tag.                                     */
  1463.         retc=bkm_process(line,tag,flag,sameline,strip(otherlines),strip(beforelines))
  1464. /* Get the line which contains the cursor. If there is  */
  1465. /* something after the cursor we have to switch         */
  1466. /* inserting on.                                        */
  1467.         getline line                    -- get current line
  1468.         if substr(line,.col)<>'' then   -- something after the cursor?
  1469.           if not insert_state() then insert_toggle       -- insert on if yes
  1470. compile if EVERSION >= '5.50'
  1471.              call fixup_cursor()
  1472. compile endif
  1473.            endif
  1474.         endif
  1475. /* If the dynamic margins are configured, check it too. */
  1476. compile if bkm_tags_between<>''
  1477.         parse value line with xtag .                    -- get tag
  1478.         parse value xtag with xtag (bkm_tag_end) .      -- remove tag-end
  1479.         if xtag<>tag then -- not the same? (that means that the cursor is not in the line which contains the tag)
  1480.           if pos(tag||' ',bkm_tags_between||' ') then   -- tag in list?  [LAM: change to wordpos() for 5.20+?]
  1481.             'ma 1 254 1'                        -- reset margins
  1482. compile if bkm_debugging
  1483.             if bkm_debug then call bkm_say("Margins changed to 1 254 1.",0) endif
  1484. compile endif
  1485.             call bkm_upd_files(-1,tag)          -- store in hidden file
  1486.             bkm_between_new=tag                 -- set flag
  1487.           endif
  1488.         endif
  1489. compile endif
  1490.       endif
  1491. compile if bkm_want_symbols
  1492.     else                              -- else check for replacement
  1493.       retc=0                            -- set bad return code
  1494.       if bkm_sym_file<>'' then        -- symbol support active?
  1495.         if pos(bkm_tag_start,bkm_symbols) then  -- if key found in table continue
  1496.           getfileid id,bkm_sym_file   -- get id of symbol file
  1497.           if id<>'' then              -- if available
  1498.             getline line,asc(bkm_tag_start),id  -- get the line from the symbol file
  1499.             parse value line with . k .       -- get the replacement string
  1500.             keyin k                     -- type the variable
  1501.             retc=1                      -- good return code
  1502.           endif
  1503.         endif
  1504.       endif
  1505. compile else
  1506.     else
  1507.       retc=0
  1508. compile endif
  1509.     endif
  1510.   else
  1511.     retc=0
  1512.   endif
  1513. return retc
  1514.  
  1515. /* Generic routine to insert the tag and optionally     */
  1516. /* the parameters into the same, or into multiple       */
  1517. /* lines. The input parameters are:                     */
  1518. /*  1 ... the part of the line to the left of the tag   */
  1519. /*  2 ... the tag (without the ending period)           */
  1520. /*  3 ... a switch. This switch can be:                 */
  1521. /*        1 ... force tag on new line, leave linerest   */
  1522. /*              on old line.                            */
  1523. /*        2 ... force tag on new line, move linerest    */
  1524. /*              after the tag.                          */
  1525. /*        3 ... leave tag where it is, if add. tag      */
  1526. /*              defines, put on end of line.            */
  1527. /*        4 ... additional tags contain file name which */
  1528. /*              should be inserted. Parameters are      */
  1529. /*              resolved as if flag=1.                  */
  1530. /*        5 ... same as 4, but tag is not inserted into */
  1531. /*              text.                                   */
  1532. /*  4 ... the parameters which should be inserted       */
  1533. /*  5 ... other tags which have to be inserted into     */
  1534. /*        new lines, or the same line (flag=3)          */
  1535. /*  6 ... other stuff which should be inserted before   */
  1536. /*        the line with the tag.                        */
  1537. defproc bkm_process(line,tag,force,parms,xother,beforelines)
  1538.   universal bkm_last_colon
  1539.   universal linerest
  1540.   universal bkm_save_file
  1541.   universal bkm_nocheck
  1542.   universal bkm_tag_end
  1543.   universal bkm_keepspace
  1544. compile if bkm_attr
  1545.   universal bkm_did_bkmattr
  1546. compile endif
  1547. compile if bkm_debugging
  1548.   universal bkm_debug
  1549.   if bkm_debug then call bkm_say("bkm_process("line","tag","force","parms","xother","beforelines")",0) endif
  1550. compile endif
  1551.   if force > 10 then
  1552.     force = force - 10
  1553.     bkm_keepspace = 1
  1554.   endif
  1555.   if line='' & linerest='' & not bkm_keepspace then bkm_last_colon=1 endif  -- move tag to position one
  1556.   savepos=pos('#',parms)                -- save new cursor postition
  1557.   cursor=savepos+length(tag)+bkm_last_colon-1   -- calculate new position
  1558. /* Remove the number (hash) sign from the parameters    */
  1559.   -- LAM:  If we know there's always a '#', could replace next two lines (if 5.20 or above):
  1560.   parse value parms with p1 '#' p2
  1561.   parms=p1||p2                  -- concatinate parameter
  1562.   -- with:  parms = delstr(parms, savepos, 1)
  1563. /* Save current line number, this is where the cursor   */
  1564. /* should go.                                           */
  1565.   new_line=.line
  1566.   if force=1 | force=4 then             -- tag must start in new line
  1567.     if bkm_last_colon=1 & linerest='' then      -- is alread there?
  1568.       replaceline tag||parms                    -- put tag and parms in line
  1569.     else
  1570. /* Remove the tag from the middle of the line, and      */
  1571. /* create a separate line for the tag.                  */
  1572.       replaceline line||linerest
  1573. compile if bkm_attr
  1574.       if bkm_did_bkmattr=1 then call bkm_upd_line_attr(.line) endif
  1575. compile endif
  1576. /* Now we have to redefine the cursor position          */
  1577.       cursor=cursor-bkm_last_colon+1
  1578.       if bkm_keepspace then
  1579.         if strip(line||linerest) = '' then
  1580.           replaceline substr(' ',1,length(line))||tag||parms
  1581.         else
  1582.           insertline substr(' ',1,length(line))||tag||parms,.line+1
  1583. /* The tag is on the next line, therefore we have to    */
  1584. /* position the cursor one line down.                   */
  1585.           new_line=new_line+1
  1586.           down
  1587.         endif
  1588.         cursor=cursor+length(line)
  1589.       else
  1590.         insertline tag||parms,.line+1
  1591. /* The tag is on the next line, therefore we have to    */
  1592. /* position the cursor one line down.                   */
  1593.         new_line=new_line+1
  1594.         down
  1595.       endif
  1596.     endif
  1597.     if force=4 then             -- get additional lines from file
  1598. /* xother contains file name                            */
  1599.       call bkm_get(strip(upcase(xother)))
  1600.       if rc<>0 then                             -- file not found, tell user
  1601.         call bkm_say("File" strip(upcase(xother)) "not found, repair" bkm_save_file".",0)
  1602. compile if EVERSION < 4
  1603.       else
  1604.         call bkm_init()                         -- initialize support
  1605. compile endif
  1606.       endif
  1607.       xother=''                                 -- cleanup
  1608.     endif
  1609.   elseif force=2 then
  1610. /* Remove the tag from the middle of the line, but      */
  1611. /* move the remainder of the line after the tag.        */
  1612.     if bkm_last_colon=1 then            -- tag-start in column 1?
  1613.       replaceline tag||parms||linerest  -- insert tag in position 1
  1614.     else
  1615.       replaceline line                  -- store stuff left of the tag
  1616. compile if bkm_attr
  1617.       if bkm_did_bkmattr=1 then call bkm_upd_line_attr(.line) endif
  1618. compile endif
  1619.       cursor=cursor-bkm_last_colon+1    -- position cursor
  1620.       if bkm_keepspace then
  1621.         if strip(line||linerest) = '' then
  1622.           replaceline substr(' ',1,length(line))||tag||parms||linerest   -- create a new line with the rest
  1623.         else
  1624.           insertline substr(' ',1,length(line))||tag||parms||linerest,.line+1   -- create a new line with the rest
  1625.           new_line=new_line+1               -- down one line
  1626.           down
  1627.         endif
  1628.         cursor=cursor+length(line)
  1629.       else
  1630.         insertline tag||parms||linerest,.line+1   -- create a new line with the rest
  1631.         new_line=new_line+1               -- down one line
  1632.         down
  1633.       endif
  1634.     endif
  1635.   elseif force=3 then                   -- tag may be anywhere in the line
  1636.     if bkm_last_colon=1 & linerest='' then      -- we are in position 1
  1637.       replaceline tag||parms            -- store tag and parameters
  1638.     else
  1639. /* This is a special case. The tag has been in the middle of a  */
  1640. /* line, we don't want to generate additional lines. So we      */
  1641. /* take the stuff which would otherwise go in new lines, and    */
  1642. /* put it in the line where the tag is.                         */
  1643.       parse value xother with p1 '#' p2 -- remove #
  1644.       xother=p1||p2                     -- concatenate
  1645.       parse value xother with p1 '\' p2 -- remove new line
  1646.       xother=p1||p2                     -- concatenate again
  1647.       replaceline line||tag||parms||linerest||xother -- replace line
  1648.       xother=''                         -- cleanup
  1649.     endif
  1650.   elseif force=5 then                   -- get data from file
  1651. /* xother contains file name                            */
  1652.     call bkm_get(strip(upcase(xother)))
  1653.     if rc then                             -- file not found, tell user
  1654.       call bkm_say("File" strip(upcase(xother)) "not found, repair" bkm_save_file".",0)
  1655. compile if EVERSION < 4
  1656.     else
  1657.       call bkm_init()                         -- initialize support
  1658. compile endif
  1659.     endif
  1660.     xother=''                                 -- cleanup
  1661.     if line||linerest='' then           -- tag was on empty line
  1662.       deleteline                        -- delete line
  1663.     else                                -- otherwise
  1664.       replaceline line||linerest        -- remove tag from line
  1665.       new_line=new_line+1               -- position cursor
  1666.       down
  1667.     endif
  1668.     getline xline,new_line              -- get new cursor position
  1669.     cursor=length(strip(xline))+1
  1670.   else
  1671.     call bkm_say('Flag' force 'for' tag 'invalid, repair' bkm_save_file".",0)
  1672.   endif
  1673. compile if bkm_attr
  1674.   if bkm_did_bkmattr=1 then call bkm_upd_line_attr(.line) endif
  1675. compile endif
  1676. /* Now generate additional lines, if any.               */
  1677.   if beforelines<>'' then               -- anything to add before the tag?
  1678.     loop                                -- loop over data
  1679.       parse value beforelines with iline '\' beforelines -- get CR
  1680.       if beforelines='' & iline='' then leave endif     -- any more data?
  1681.       if substr(iline,1,1)='%' then
  1682.         filename=upcase(strip(substr(iline,2)))
  1683.         savesize=.last                          -- save current size
  1684.         '-1'                                    -- back one line
  1685.         call bkm_get(filename)
  1686.         if rc then                             -- file not found, tell user
  1687.           call bkm_say("File" filename "not found, repair" bkm_save_file".",0)
  1688.           '+1'
  1689.         else
  1690.           new_line=new_line+.last-savesize        -- new line position
  1691. compile if EVERSION < 4
  1692.           call bkm_init()                         -- initialize support
  1693. compile endif
  1694.         endif
  1695.       else
  1696.         insertline iline,.line            -- yes, insert line, even if blank
  1697. compile if bkm_attr
  1698.         if bkm_did_bkmattr=1 then call bkm_upd_line_attr(.line) endif
  1699. compile endif
  1700.         new_line=new_line+1               -- remember new line position
  1701.       endif
  1702.       new_line                            -- set global
  1703.     endloop
  1704.   endif
  1705.   if xother<>'' then
  1706.     i=0
  1707.     loop                                  -- loop over stuff after the tag
  1708.       i=i+1
  1709.       parse value xother with iline '\' xother    -- get CR
  1710.       if xother='' & iline='' then leave endif    -- exit loop if nothing else
  1711.       if substr(iline,1,1)='%' then
  1712.         filename=upcase(strip(substr(iline,2)))
  1713.         savesize=.last                          -- save current size
  1714.         saveline=.line
  1715.         .line=.line+i-1                         -- calculate where it should go
  1716.         call bkm_get(filename)
  1717.         if rc then                             -- file not found, tell user
  1718.           call bkm_say("File" filename "not found, repair" bkm_save_file".",0)
  1719.           .line=.line+1-i
  1720.         else
  1721.           i=i+.last-savesize-1                    -- set new index
  1722.           saveline
  1723. compile if EVERSION < 4
  1724.           call bkm_init()                         -- initialize support
  1725. compile endif
  1726.         endif
  1727.       else
  1728.         insertline iline,.line+i            -- insert data
  1729.         x=pos('#',iline)                    -- cursor in this line?
  1730.         y=pos('@',iline)
  1731.         if x | y then                         -- yes, '#' found
  1732.           if x>1 then                       -- position at first column?
  1733. compile if EVERSION >= '5.20'
  1734.             iline = delstr(iline, x, 1)     -- no, delete that character
  1735. compile else
  1736.             parse value iline with p1 '#' p2  -- no, get before and after
  1737.             iline=p1||p2                    -- concatinate them
  1738. compile endif
  1739.           elseif y>1 then                   -- position at first column?
  1740. compile if EVERSION >= '5.20'
  1741.             iline = delstr(iline, y, 1)     -- no, delete that character
  1742. compile else
  1743.             parse value iline with p1 '@' p2  -- no, get before and after
  1744.             iline=p1||p2                    -- concatinate them
  1745. compile endif
  1746.           else
  1747.             iline=strip(substr(iline,2))    -- get rest of line
  1748.           endif
  1749.           replaceline iline,.line+i         -- replace the line
  1750. /* Now we have to check if the cursor is already positioned in  */
  1751. /* the line with the tag. If not, we can move it to this        */
  1752. /* position safely.                                             */
  1753.           if parms=bkm_tag_end | not savepos | y then  -- only default cursor?
  1754.             cursor=x+y                      -- yes, set cursor
  1755.             new_line=.line+i                -- set new line position
  1756.           endif
  1757.         endif
  1758. compile if bkm_attr
  1759.         if bkm_did_bkmattr=1 then call bkm_upd_line_attr(.line+i) endif
  1760. compile endif
  1761.       endif
  1762.     endloop
  1763.   endif
  1764. /* At the end we have to set the new cursor position.   */
  1765.   .col=cursor                           -- set cursor position
  1766.   new_line                              -- move cursor to correct line
  1767. return 1
  1768.  
  1769. /* The next routine checks the tag. If it is valid, the */
  1770. /* return code contains the line number of the tag in   */
  1771. /* the tag-definition file. If not, the return code is  */
  1772. /* zero. If an inconsistency is found, the return code  */
  1773. /* is set to -1.                                        */
  1774. defproc bkm_find_tag(tag)
  1775.   universal bkm_line_text
  1776.   universal bkm_def
  1777.   universal bkm_idx
  1778. compile if bkm_debugging
  1779.   universal bkm_debug
  1780.   if bkm_debug then call bkm_say('Searching for tag' tag".",0) endif
  1781. compile endif
  1782. /* Save the id of the current file.                     */
  1783. /* Get the id of the index file.                        */
  1784.   getfileid id,bkm_idx                  -- get id of index
  1785.   if id='' then return -1 endif         -- exit if index not found
  1786. /* A word to the index. The first line of the index     */
  1787. /* contains the names of the current tag-definition     */
  1788. /* files. This is checked somewhere else. At this point */
  1789. /* we can be sure that the index points to the right    */
  1790. /* tag-definition file.                                 */
  1791.   for i = 2 to 9999                     -- loop over index
  1792.     if i>id.last then leave endif       -- end of file?
  1793.     getline tagline,i,id                -- no, get line from index
  1794.     xpos=pos(tag||' ',tagline)          -- check for tag
  1795.     if xpos then                      -- tag found
  1796.       xtag=substr(tagline,xpos)         -- make tag first word
  1797.       parse value xtag with curtag curline .    -- get tag and line number
  1798.       getfileid id,bkm_def              -- get id of definition file
  1799.       if id='' then return -1 endif     -- exit if no definition file found
  1800.       getline bkm_line_text,curline,id  -- get the line with the number found in the index
  1801.       parse value bkm_line_text with istag flag . -- get tag and flag
  1802.       if istag<>tag then return -1 endif -- same tag? If not -> inconsistant
  1803.       if flag='-' then return 0 endif   -- tag "undefined" ?
  1804.       return curline                    -- return data to caller
  1805.     endif
  1806.   endfor
  1807. return 0                                -- no luck, no tag
  1808.  
  1809. /* Routine to display text on the status line. If debug */
  1810. /* is on, also wait for a key.                          */
  1811. defproc bkm_say(msg,flag)
  1812. compile if bkm_debugging
  1813.   universal bkm_debug
  1814.   if bkm_debug then flag=1 endif        -- wait for key in debug mode
  1815. compile endif
  1816.   if flag=1 then                        -- wait for key?
  1817. compile if EVERSION < 5
  1818.     msg=msg||' ...'                     -- yes, put ellipses after text
  1819. compile endif
  1820.     call messageNwait("EBOOKIE: "msg)   -- prefix message with "EBOOKIE"
  1821. compile if EVERSION < 5
  1822.     getfileid curfileid                 -- get current id
  1823.     sayerror 0                          -- clean message area
  1824.     activatefile curfileid              -- get back current file
  1825. compile endif
  1826.   else                                  -- don't wait for key
  1827.     call message("EBOOKIE: "msg)        -- call appropriate routine
  1828.   endif
  1829.  
  1830. /* The following routine is accessed at the time the    */
  1831. /* file is read from the disk. First we have to check   */
  1832. /* for the footprint ".* EBOOKIE". Then the extension   */
  1833. /* checked. Finally, if configured, we check a user-    */
  1834. /* defined number of lines for a valid tag. If the      */
  1835. /* tag we find is invalid, we don't start the support,  */
  1836. /* If it is OK; we start EBOOKIE.                       */
  1837. /*                                                      */
  1838. /* In E3 this routine is also accessed whenever the user*/
  1839. /* switches from one file to the other in the ring,     */
  1840. /* therefore we have to take care of that too.          */
  1841. /*                                                      */
  1842. defproc bkm_init()
  1843.   universal bkm_last_colon
  1844.   universal bkm_def
  1845.   universal bkm_idx
  1846.   universal bkm_avail
  1847.   universal bkm_message
  1848. compile if bkm_debugging
  1849.   universal bkm_debug
  1850. compile endif
  1851.   universal bkm_nocheck
  1852.   universal bkm_save_file
  1853.   universal bkm_cur_num
  1854.   universal bkm_rep_tag
  1855.   universal bkm_tag_start
  1856.   universal bkm_tag_end
  1857.   universal bkm_end_tag
  1858.   universal bkm_config
  1859. compile if bkm_tags_between<>''
  1860.   universal bkm_between_new
  1861. compile endif
  1862. compile if bkm_attr
  1863.   universal bkm_did_bkmattr
  1864. compile endif
  1865.   universal vTEMP_PATH
  1866.   universal vAUTOSAVE_PATH
  1867.   universal bkm_temp_path
  1868.  
  1869. compile if bkm_debugging
  1870.   if bkm_debug then call bkm_say("bkm_init()" .filename,0) endif
  1871. compile endif
  1872.  
  1873.   if bkm_temp_path='' then
  1874.     bkm_temp_path=strip(vAUTOSAVE_PATH)
  1875. compile if defined(AUTOSAVE_PATH)
  1876.     if bkm_temp_path='' then
  1877.       bkm_temp_path=strip(AUTOSAVE_PATH)
  1878.     endif
  1879. compile endif
  1880.     if bkm_temp_path='' then
  1881.       bkm_temp_path=strip(vTEMP_PATH)
  1882.     endif
  1883. compile if defined(TEMP_PATH)
  1884.     if bkm_temp_path='' then
  1885.       bkm_temp_path=strip(TEMP_PATH)
  1886.     endif
  1887. compile endif
  1888.     if bkm_temp_path<>'' then
  1889. compile if EVERSION >= '5.20'
  1890.       if rightstr(bkm_temp_path,1)<>'\' then
  1891. compile else
  1892.       if substr(bkm_temp_path,length(bkm_temp_path),1)<>'\' then
  1893. compile endif
  1894.         bkm_temp_path=bkm_temp_path||'\'
  1895.       endif
  1896.     endif
  1897.   endif
  1898. /* Skip files which we should not touch.                */
  1899.   if bkm_nocheck=1 then return 0 endif          -- internal files are not checked
  1900.   if substr(.filename,1,1)='.' then return 0 endif -- files which start with a period are not checked
  1901.   if .filename=bkm_def then return 0 endif      -- the definitions file is not checked
  1902.   if .filename=bkm_idx then return 0 endif      -- so is the index
  1903. /* Notify debugging user if we continue our work.       */
  1904. compile if bkm_debugging
  1905.   if bkm_debug then call bkm_say("bkm_init()" .filename "continues",0) endif
  1906. compile endif
  1907. compile if EVERSION < 4
  1908.   if bkm_find_file(.filename)>=0 then           -- look for file in hidden table
  1909.     call bkm_select()                           -- start the support
  1910.     return 0                                    -- return to caller
  1911.   endif
  1912. compile endif
  1913.   bkm=0                                 -- cleanup
  1914.   for i=1 to .last                      -- loop over beginning of file
  1915.     getline line,i                      -- get line
  1916.     parse value line with flag1 flag2 '(' def_file ')' . -- find footprint
  1917.     if flag1='.*' & flag2='EBOOKIE' then
  1918.       bkm=1                             -- footprint found
  1919.       leave                             -- exit loop
  1920.     endif
  1921.     if substr(flag1,1,2)<>'.*' then leave endif -- no comment, exit loop
  1922.   endfor
  1923.   if not bkm then
  1924.     def_file=bkm_def_file
  1925.     ext=filetype()
  1926. compile if EVERSION >= '5.20'
  1927.     if ext <> '' & wordpos(upcase(ext),upcase(bkm_files)) then
  1928. compile else
  1929.     x_files=bkm_files     -- LAM: assume this is because old versions of E uppercased the upcase() parm; doesn't happen with current versions.
  1930.     if pos(' '||strip(upcase(ext))||' ',' '||strip(upcase(x_files))||' ') then
  1931. compile endif
  1932.       bkm=1
  1933.       x_files=bkm_ext_def
  1934.       x=pos(strip(upcase(ext))||'=',x_files)
  1935.       if x then
  1936.         x_files=Substr(x_files,x)
  1937.         parse value x_files with . '=' def_file '=' .
  1938.         if pos('=',x_files) then
  1939.           x = lastpos(' ',def_file)
  1940.           def_file = substr(def_file,1,x)
  1941.         endif
  1942.         def_file=strip(def_file)
  1943.         If Substr(def_file,1,1) = '"' | substr(def_file,1,1) = "'" then
  1944.           def_file = Substr(def_file,2,Length(def_file)-2)
  1945.         endif
  1946.         if def_file = '' then def_file=bkm_def_file endif
  1947.       endif
  1948. compile if bkm_search > 0
  1949.     else
  1950.       search=max(bkm_search, 10)
  1951. /* Now search the first 100 lines of the file, or at    */
  1952. /* least the number of lines the user has specified.    */
  1953.       for i=1 to search
  1954.         if i=.last then leave endif
  1955.         getline line,i
  1956.         parse value line with tag .
  1957.         if substr(tag,1,1)<>bkm_tag_start then iterate endif
  1958.         parse value tag with tag (bkm_tag_end) .
  1959.         if length(tag)<2 then iterate endif
  1960.         if bkm_avail=-1 then
  1961.           call bkm_chg_def_file(def_file,0)
  1962.         endif
  1963.         if bkm_avail=0 then return 0 endif
  1964.         if bkm_find_tag(lowcase(tag))=0 then leave endif
  1965.         bkm=1
  1966.         leave
  1967.       endfor
  1968. compile endif
  1969.     endif
  1970.   endif
  1971.   bkm_rep_tag=''
  1972.   if bkm<>0 then
  1973.     call bkm_chg_def_file(def_file,0)
  1974.     if bkm_avail=0 then return 0 endif
  1975.     bkm=bkm_cur_num
  1976.     call bkm_upd_line_one()
  1977. compile if E3
  1978.     keys bkm_keys
  1979. compile endif
  1980. compile if bkm_dont_touch_margins=0
  1981.     'ma' bkm_margins
  1982. compile endif
  1983.     join_after_wrap=0
  1984.     bkm_last_colon=0
  1985. compile if EVERSION < 5
  1986.     c_state = command_state()
  1987.     if c_state then commandtoggle; endif
  1988. compile endif
  1989.     if bkm_config <> '' then
  1990.       'xcom L /.mod' bkm_config'/ca'
  1991.       bkm_config = ''
  1992.     else
  1993.       top
  1994.       down
  1995.     endif
  1996. compile if EVERSION < 5
  1997.     if c_state then commandtoggle; endif
  1998. compile endif
  1999. compile if bkm_attr
  2000.     bkm_did_bkmattr=1
  2001.     call attribute_on(1)  -- "Color attributes" flag
  2002.     call attribute_on(8)  -- "Save attributes" flag
  2003. compile if bkm_attr_init=1
  2004.     call bkm_add_attr('on')
  2005. compile endif
  2006. compile endif
  2007.   endif
  2008.   call bkm_upd_files(bkm,' ')
  2009. compile if bkm_tags_between<>''
  2010.   bkm_between_new=''
  2011. compile endif
  2012. compile if bkm_debugging
  2013.   if bkm_debug then call bkm_say("bkm_init()" .filename" ended, rc="bkm,0) endif
  2014. compile endif
  2015. return bkm
  2016.  
  2017. /* The following routine is called during the DEFSELECT */
  2018. /* processing in EOS2 or EPM, or during the             */
  2019. /* select_edit_keys() processing in E3.                 */
  2020. defproc bkm_select()
  2021.   universal bkm_last_colon
  2022. compile if bkm_tags_between<>''
  2023.   universal bkm_between
  2024.   universal bkm_between_new
  2025. compile endif
  2026. compile if bkm_debugging
  2027.   universal bkm_debug
  2028.   if bkm_debug then call bkm_say("bkm_select() called for ".filename,0) endif
  2029. compile endif
  2030.   bkm=bkm_find_file(.filename)
  2031.   if bkm>0 then
  2032. compile if E3
  2033.     keys bkm_keys
  2034. compile if bkm_dont_touch_margins=0
  2035.     'ma' bkm_margins
  2036. compile endif
  2037.     join_after_wrap=0
  2038. compile endif
  2039.     bkm_last_colon=0
  2040.     call bkm_switch(bkm)
  2041. compile if bkm_tags_between<>''
  2042.     bkm_between_new=bkm_between
  2043.     if bkm_between<>'' then
  2044.       'ma 1 254 1'
  2045.     endif
  2046. compile endif
  2047. compile if E3
  2048.   else
  2049.     ext=filetype()
  2050.     if ext='' then
  2051.       keys edit_keys
  2052. compile if bkm_dont_touch_margins=0
  2053.       'tabs' DEFAULT_TABS
  2054.       'ma' DEFAULT_MARGINS
  2055. compile endif
  2056. compile if E_SYNTAX_ASSIST and ALTERNATE_KEYSETS
  2057.     elseif ext='E' then
  2058.        keys e_keys
  2059. compile if bkm_dont_touch_margins=0
  2060.        'tabs' E_TABS
  2061.        'ma'   E_MARGINS
  2062. compile endif
  2063. compile endif
  2064. compile if C_SYNTAX_ASSIST and ALTERNATE_KEYSETS
  2065.     elseif ext='C' then
  2066.        keys c_keys
  2067. compile if bkm_dont_touch_margins=0
  2068.        'tabs' C_TABS
  2069.        'ma'   C_MARGINS
  2070. compile endif
  2071. compile endif
  2072. compile if P_SYNTAX_ASSIST and ALTERNATE_KEYSETS
  2073.     elseif ext='PAS' | ext='PASCAL' then
  2074.        keys pas_keys
  2075. compile if bkm_dont_touch_margins=0
  2076.        'tabs' P_TABS
  2077.        'ma'   P_MARGINS
  2078. compile endif
  2079. compile endif
  2080. compile if REXX_SYNTAX_ASSIST and ALTERNATE_KEYSETS
  2081.     elseif ext='BAT' | ext='CMD' | ext='EXC' | ext='EXEC' | ext='XEDIT' then
  2082.       getline line,1
  2083.       if substr(line,1,2)='/*' or (line='' & .last = 1) then
  2084.         keys rexx_keys
  2085. compile if bkm_dont_touch_margins=0
  2086.         'tabs' REXX_TABS
  2087.         'ma'   REXX_MARGINS
  2088. compile endif
  2089.       endif
  2090. compile endif
  2091.     else
  2092.       keys edit_keys
  2093. compile if bkm_dont_touch_margins=0
  2094.       'tabs' DEFAULT_TABS
  2095.       'ma' DEFAULT_MARGINS
  2096. compile endif
  2097.     endif
  2098. compile endif
  2099.   endif
  2100. return 0
  2101.  
  2102. /* Open or change the tag-definition files.             */
  2103. defproc bkm_chg_def_file(file,force)
  2104.   universal bkm_def
  2105.   universal bkm_idx
  2106.   universal bkm_avail
  2107.   universal bkm_nocheck
  2108.   universal bkm_save_file
  2109.   universal bkm_num
  2110.   universal bkm_cur_num
  2111. compile if bkm_want_symbols
  2112.   universal bkm_symbols
  2113.   universal bkm_sym_file
  2114.   universal bkm_codepage
  2115. compile endif
  2116.   universal bkm_tag_start
  2117.   universal bkm_tag_end
  2118.   universal bkm_end_tag
  2119.   universal bkm_rep_tag
  2120.   universal bkm_inv_tag_rep
  2121.   universal bkm_temp_path
  2122. compile if bkm_debugging
  2123.   universal bkm_debug
  2124.   if bkm_debug then call bkm_say("bkm_chg_def_file("file","force")",0) endif
  2125. compile endif
  2126.   savefile=upcase(strip(file))
  2127.   save_def=bkm_def
  2128.   save_idx=bkm_idx
  2129.   save_avail=bkm_avail
  2130.   save_cur_num=bkm_cur_num
  2131. compile if bkm_want_symbols
  2132.   save_symbols=bkm_symbols
  2133.   save_sym_file=bkm_sym_file
  2134. compile endif
  2135.   if not force then
  2136.     for i = 1 to 99
  2137.       xrc=bkm_switch(i)
  2138.       if xrc=1 then leave endif
  2139.       if savefile=bkm_save_file then
  2140.         getfileid id,'.BKM'
  2141. compile if EVERSION < '5.0'
  2142.         save_command_state=command_state()
  2143.         if save_command_state then commandtoggle endif
  2144. compile endif
  2145.         for j=1 to id.last
  2146.           getline line,j,id
  2147.           parse value line with fname '==' retc '||' .
  2148.           if retc=i then
  2149.             call bkm_find_file(fname)
  2150.             leave
  2151.           endif
  2152.         endfor
  2153. compile if EVERSION < '5.0'
  2154.         if save_command_state then commandtoggle endif
  2155. compile endif
  2156.         getfileid bkm_def_fileid,bkm_def
  2157.         getline tag_fline,1,bkm_def_fileid
  2158.         call bkm_get_parms(tag_fline,1)
  2159. compile if bkm_want_symbols
  2160.         if bkm_sym_file<>'' then
  2161.           bkm_sym_file=upcase(bkm_sym_file||'.'||bkm_codepage)
  2162.         endif
  2163. compile endif
  2164.         return 0
  2165.       endif
  2166.     endfor
  2167.   endif
  2168.   getfileid curfileid
  2169.   parse value upcase(file) with file .
  2170.   retc=0
  2171.   bkm_avail=1
  2172.   bkm_def=bkm_findfile(file)
  2173.   if bkm_def='' then bkm_avail=0 endif
  2174.   if bkm_avail=1 then
  2175.     bkm_path=''
  2176.     bkm_def=upcase(bkm_def)
  2177.     x=lastpos('\',bkm_def)
  2178.     if x then bkm_path=substr(bkm_def,1,x) endif
  2179.     bkm_nocheck=1
  2180.     if save_def<>'' & force=1 then
  2181.       getfileid id,save_def
  2182.       if id<>'' then
  2183.         activatefile id
  2184.         .modify=0
  2185.         'quit'
  2186.       endif
  2187.     endif
  2188.     if save_idx<>'' & force=1 then
  2189.       getfileid id,save_idx
  2190.       if id<>'' then
  2191.         activatefile id
  2192.         .modify=0
  2193.         'quit'
  2194.       endif
  2195.     endif
  2196.     activatefile curfileid
  2197. compile if bkm_debugging
  2198.     if bkm_debug then call bkm_say("Inititalizing tag support.",0) endif
  2199. compile endif
  2200. compile if EVERSION > 5
  2201.     'xcom edit' bkm_def
  2202.     .visible=0
  2203. compile else
  2204.     'xcom edit /h /q' bkm_def
  2205. compile endif
  2206.     bkm_save_file=substr(bkm_def,length(strip(bkm_path))+1)
  2207.     x=lastpos('.',bkm_save_file)
  2208.     if x then
  2209.       bkm_idx=substr(bkm_save_file,1,x)||'IDX'
  2210.     else
  2211.       bkm_idx=bkm_save_file||'.IDX'
  2212.     endif
  2213.     if force=1 then
  2214.       bkm_def='.D'||strip(save_cur_num)
  2215.       bkm_cur_num=save_cur_num
  2216.     else
  2217.       bkm_def='.D'||strip(bkm_num)
  2218.       bkm_cur_num=bkm_num
  2219.       bkm_num=bkm_num+1
  2220.     endif
  2221.     .filename=bkm_def
  2222.     getfileid bkm_def_fileid
  2223.     getline tag_fline,1,bkm_def_fileid
  2224.     call bkm_get_parms(tag_fline,1)
  2225.     msg=''
  2226.     parse value savefile with . savefile
  2227.     for i=1 to 9
  2228.       parse value savefile with file savefile
  2229.       if file=' ' then leave endif
  2230.       '0'
  2231.       call bkm_get(strip(upcase(file)))
  2232.       if rc then
  2233.         msg=msg||' '||strip(upcase(file))
  2234.       else
  2235.         activatefile bkm_def_fileid
  2236.         bkm_save_file=bkm_save_file||' '||strip(upcase(file))
  2237.         getline tag_fline,1,bkm_def_fileid
  2238.         call bkm_get_parms(tag_fline,0)
  2239. compile if bkm_want_symbols
  2240.         tag_fline='* EBOOKIE tag_start='||bkm_tag_start||' tag_end='||bkm_tag_end||' end_tag='||bkm_end_tag||' a_2='||bkm_rep_tag||' invalid='||bkm_inv_tag_rep||' symbols='||bkm_sym_file
  2241. compile else
  2242.         tag_fline='* EBOOKIE tag_start='||bkm_tag_start||' tag_end='||bkm_tag_end||' end_tag='||bkm_end_tag||' a_2='||bkm_rep_tag||' invalid='||bkm_inv_tag_rep
  2243. compile endif
  2244.         replaceline tag_fline,1,bkm_def_fileid
  2245.       endif
  2246.     endfor
  2247.     .modify=0
  2248.     if msg<>'' then
  2249.       activatefile curfileid
  2250.       call bkm_say("The file(s)"msg "could not be found.",1)
  2251.     endif
  2252.     line='.* EBOOKIE ('||Strip(bkm_save_file)||')'
  2253.     if bkm_temp_path='' then bkm_temp_path=bkm_path endif
  2254.     bkm_idx=bkm_temp_path||bkm_idx
  2255. compile if EVERSION > 5
  2256.     'xcom edit' bkm_idx
  2257.     .visible=0
  2258. compile else
  2259.     'xcom edit /h /q' bkm_idx
  2260. compile endif
  2261.     .filename=bkm_idx
  2262.     getfileid bkm_idx_fileid
  2263.     if not rc then
  2264.       maxlines=.last
  2265.       getline oline,1
  2266.       if oline<>line | force=1 then
  2267.         for i=1 to maxlines
  2268.           deleteline 1
  2269.           if rc then leave endif
  2270.         endfor
  2271.         rc=1
  2272.       endif
  2273.     endif
  2274.     if rc then
  2275.       activatefile curfileid
  2276.       call bkm_say("Inititalizing tag support, creating tag index, please wait...",0)
  2277.       activatefile bkm_def_fileid
  2278.       j=1
  2279.       bkm_tags=''
  2280.       for i=1 to 9999
  2281.         if i>.last then leave endif
  2282.         getline tline,i
  2283.         parse value tline with xtag rest
  2284.         if substr(xtag,1,1)<>bkm_tag_start then iterate endif
  2285.         bkm_tags=bkm_tags||' '||strip(xtag)||' '||i
  2286.         if length(bkm_tags)>240 then
  2287.           activatefile bkm_idx_fileid
  2288.           if j=1 then
  2289.             insertline line,j
  2290.             j=j+1
  2291.           endif
  2292.           insertline lowcase(strip(bkm_tags)),j
  2293.           j=j+1
  2294.           bkm_tags=''
  2295.           activatefile bkm_def_fileid
  2296.         endif
  2297.       endfor
  2298.       if length(bkm_tags) then
  2299.         activatefile bkm_idx_fileid
  2300.         if j=1 then
  2301.           insertline line,j
  2302.           j=j+1
  2303.         endif
  2304.         insertline lowcase(strip(bkm_tags)),j
  2305.       endif
  2306.       activatefile bkm_idx_fileid
  2307.       'xcom save' bkm_idx
  2308.     endif
  2309.     if force=1 then
  2310.       bkm_idx='.I'||strip(save_cur_num)
  2311.     else
  2312.       bkm_idx='.I'||strip(bkm_cur_num)
  2313.     endif
  2314.     .filename=bkm_idx
  2315.     .modify=0
  2316.     activatefile curfileid
  2317. compile if bkm_want_symbols
  2318. compile if bkm_debugging
  2319.     if bkm_debug then call bkm_say("Checking symbol support, file="upcase(bkm_sym_file||'.'||bkm_codepage),0) endif
  2320. compile endif
  2321.     if bkm_sym_file<>'' & bkm_codepage<>'' then
  2322.       bkm_sym_file=upcase(bkm_sym_file||'.'||bkm_codepage)
  2323.       getfileid id,bkm_sym_file
  2324.       if id='' then
  2325. compile if bkm_debugging
  2326.         if bkm_debug then call bkm_say("Inititalizing symbol table.",0) endif
  2327. compile endif
  2328.         bkm_symbols=''
  2329.         xfile=bkm_findfile(bkm_sym_file)
  2330.         if xfile<>'' then
  2331. compile if EVERSION > 5
  2332.           'xcom edit' xfile
  2333.           .visible=0
  2334. compile else
  2335.           'xcom edit /h /q' xfile
  2336. compile endif
  2337.           if rc then
  2338.             call bkm_say("Error during load of" bkm_sym_file" rc=" rc", symbol support not active.",0)
  2339.             bkm_sym_file=''
  2340.             bkm_symbols=''
  2341.           else
  2342.             .filename=bkm_sym_file
  2343.             getline nosym,1
  2344.             deleteline 1
  2345.             .modify=0
  2346. compile if E3
  2347.             for i=33 to .last           -- skip x'00' to x'20' in E3
  2348. compile else
  2349.             for i=1 to .last
  2350. compile endif
  2351.               getline iline,i
  2352.               if asc(substr(iline,1,1))=i then
  2353.                 parse value iline with char symbol '--' .
  2354.                 if symbol<>'' then
  2355.                   if not pos(strip(char),nosym) then
  2356.                     bkm_symbols=bkm_symbols||strip(char)
  2357.                   endif
  2358.                 endif
  2359.               endif
  2360.             endfor
  2361.             bkm_symbols=strip(bkm_symbols)
  2362.           endif
  2363.           activatefile curfileid
  2364.         else
  2365.           call bkm_say("Could not locate the file" bkm_sym_file", symbol support not active.",0)
  2366.           bkm_sym_file=''
  2367.           bkm_symbols=''
  2368.         endif
  2369.       endif
  2370.     else
  2371.       bkm_sym_file=''
  2372.       bkm_symbols=''
  2373.     endif
  2374. compile endif
  2375.     bkm_nocheck=0
  2376.   else
  2377.     bkm_def=save_def
  2378.     bkm_idx=save_idx
  2379.     bkm_avail=save_avail
  2380.     bkm_cur_num=save_cur_num
  2381. compile if bkm_want_symbols
  2382.     bkm_symbols=save_symbols
  2383.     bkm_sym_file=save_sym_file
  2384. compile endif
  2385.     if bkm_avail=1 then
  2386.       call bkm_say("Could not find the file" file", support status unchanged.",0)
  2387.     else
  2388.       call bkm_say("Could not find the file" file", support not available.",0)
  2389.       bkm_avail=0
  2390.     endif
  2391.     retc=1
  2392.   endif
  2393.   activatefile curfileid
  2394. return retc
  2395.  
  2396. defproc bkm_upd_line_one()
  2397.   universal bkm_save_file
  2398. compile if bkm_debugging
  2399.   universal bkm_debug
  2400.   if bkm_debug then call bkm_say("bkm_upd_line_one()",0) endif
  2401. compile endif
  2402.   oldmod=.modify
  2403.   footprint='.* EBOOKIE ('||Strip(bkm_save_file)||')'
  2404.   if .last<1 then
  2405.     insertline footprint,1
  2406.   else
  2407.     for i=1 to .last
  2408.       getline oline,i
  2409.       parse value oline with flag1 flag2 .
  2410.       if flag1='.*' & flag2='EBOOKIE' then
  2411.         if oline<>footprint then
  2412.           replaceline footprint,i
  2413.         endif
  2414.         leave
  2415.       endif
  2416.       if substr(flag1,1,2)<>'.*' then
  2417.         insertline footprint,i
  2418.         if .last=2 & textline(2)='' then  -- A new file;
  2419.           .modify=oldmod                  -- allow quitting without prompt
  2420.         endif
  2421.         leave
  2422.       endif
  2423.     endfor
  2424.   endif
  2425. ; .modify=oldmod
  2426.  
  2427. defproc bkm_switch(num)
  2428.   universal bkm_save_file
  2429.   universal bkm_def
  2430.   universal bkm_idx
  2431.   universal bkm_cur_num
  2432. compile if bkm_debugging
  2433.   universal bkm_debug
  2434.   if bkm_debug then call bkm_say("bkm_switch("num")",0) endif
  2435. compile endif
  2436.   newidx='.I'||strip(num)
  2437.   if bkm_idx=newidx then return 0 endif
  2438.   retc=0
  2439.   getfileid id,newidx
  2440.   if id<>'' then
  2441.     getline oline,1,id
  2442.     parse value oline with flag1 flag2 '(' save_file ')' .
  2443.     if flag1='.*' & flag2='EBOOKIE' then
  2444.       bkm_idx=newidx
  2445.       bkm_def='.D'||strip(num)
  2446.       bkm_save_file=save_file
  2447.       bkm_cur_num=num
  2448.     else
  2449. compile if bkm_debugging
  2450.       if bkm_debug then call bkm_say("bkm_switch("num") file "newidx" no header",0) endif
  2451. compile endif
  2452.       retc=1
  2453.     endif
  2454.   else
  2455. compile if bkm_debugging
  2456.     if bkm_debug then call bkm_say("bkm_switch("num") file "newidx" not found",0) endif
  2457. compile endif
  2458.     retc=1
  2459.   endif
  2460. return retc
  2461.  
  2462. defproc bkm_findfile(file)
  2463. compile if bkm_debugging
  2464.   universal bkm_debug
  2465.   if bkm_debug then call bkm_say("bkm_findfile("file")",0) endif
  2466. compile endif
  2467.   if not pos('\',file) & not pos(':',file) then
  2468.     findfile xfile, file, EPATH
  2469. compile if E3
  2470.     if rc then findfile xfile, file, 'PATH' endif
  2471. compile else
  2472.     if rc then findfile xfile, file, '', 'D' endif  -- LAM: searches E(PM)PATH & DPATH
  2473. compile endif
  2474.   else
  2475.     findfile xfile, file, ''
  2476.   endif
  2477.   if not rc then return xfile endif
  2478. ; xfile=''
  2479. ; return xfile
  2480. ; LAM:  falling off the end automatically returns the null string.
  2481.  
  2482. defproc bkm_get(file)
  2483. compile if bkm_debugging
  2484.   universal bkm_debug
  2485.   if bkm_debug then call bkm_say("bkm_get("file")",0) endif
  2486. compile endif
  2487.   xfile=bkm_findfile(file)
  2488.   if xfile='' then return 1 endif
  2489.   file=xfile
  2490.   getfileid curfileid
  2491.   s_last=.last
  2492.   rc=0
  2493.   copy_rc=0
  2494.   bkm_nocheck=1
  2495. compile if EVERSION > 5
  2496. /* Note: This is a temporary fix for EPM. The "get"     */
  2497. /*       command doesn't work here. Don't ask me why... */  -- LAM:  why???
  2498.   'xcom edit' file
  2499.   .visible=0
  2500.   copy_rc=rc
  2501.   call psave_mark(save_mark)
  2502. compile if bkm_attr
  2503.   'bkmattr'
  2504. compile endif
  2505.   top
  2506.   mark_line
  2507.   bottom
  2508.   mark_line
  2509.   activatefile curfileid
  2510.   rc=0
  2511.   copy_mark
  2512.   copy_rc=copy_rc  -- LAM:  huh?
  2513.   getfileid fileid,file
  2514.   activatefile fileid
  2515.   'quit'
  2516.   activatefile curfileid
  2517.   parse value save_mark with s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt
  2518.   if fileid=s_mkfileid then
  2519.     diff=fileid.last-s_last
  2520.     if fileid.line<s_firstline then s_firstline=s_firstline+diff; endif
  2521.     if fileid.line<s_lastline then s_lastline=s_lastline+diff; endif
  2522.   endif
  2523.   call prestore_mark(s_firstline s_lastline s_firstcol s_lastcol s_mkfileid s_mt)
  2524. compile else
  2525.   'get' file
  2526.   copy_rc=rc
  2527. compile endif
  2528.   if copy_rc then
  2529.     call bkm_say("Error during 'get' of" file", cc="copy_rc".",1)
  2530.   endif
  2531.   activatefile curfileid
  2532.   bkm_nocheck=0
  2533. return copy_rc
  2534.  
  2535. defproc bkm_find_file(name)
  2536.   universal bkm_avail
  2537.   universal bkm_rep_tag
  2538. compile if bkm_tags_between<>''
  2539.   universal bkm_between
  2540. compile endif
  2541.   universal bkm_tag_start
  2542.   universal bkm_tag_end
  2543.   universal bkm_end_tag
  2544.   universal bkm_inv_tag_rep
  2545. compile if bkm_want_symbols
  2546.   universal bkm_symbols
  2547.   universal bkm_sym_file
  2548. compile endif
  2549. compile if bkm_attr
  2550.   universal bkm_did_bkmattr
  2551. compile endif
  2552. compile if bkm_debugging
  2553.   universal bkm_debug
  2554.   if bkm_debug then call bkm_say("bkm_find_file("name")",0) endif
  2555. compile endif
  2556.   retc=-1
  2557.   getfileid id,'.BKM'
  2558.   if id='' then
  2559.     call bkm_make_bkm()
  2560.     getfileid id,'.BKM'
  2561.     if id='' then
  2562.       call bkm_say("Could not allocate the file '.BKM', support halted.",1)
  2563.       bkm_avail=0
  2564.       return retc
  2565.     endif
  2566.   endif
  2567. compile if EVERSION < '5.0'
  2568.   save_command_state=command_state()
  2569.   if save_command_state then commandtoggle endif
  2570. compile endif
  2571.   for i=1 to id.last
  2572.     getline line,i,id
  2573.     rep_tag=''
  2574.     between=''
  2575. compile if bkm_want_symbols
  2576. compile if bkm_attr
  2577.     parse value line with fname '==' retc '||' between '||' rep_tag '||' tag_start '||' tag_end '||' end_tag '||' inv_tag_rep '||' sym_file '||' bkm_did_bkmattr .
  2578. compile else
  2579.     parse value line with fname '==' retc '||' between '||' rep_tag '||' tag_start '||' tag_end '||' end_tag '||' inv_tag_rep '||' sym_file .
  2580. compile endif
  2581. compile else
  2582. compile if bkm_attr
  2583.     parse value line with fname '==' retc '||' between '||' rep_tag '||' tag_start '||' tag_end '||' end_tag '||' inv_tag_rep '||' bkm_did_bkmattr .
  2584. compile else
  2585.     parse value line with fname '==' retc '||' between '||' rep_tag '||' tag_start '||' tag_end '||' end_tag '||' inv_tag_rep .
  2586. compile endif
  2587. compile endif
  2588.     if fname=name then leave endif
  2589.   endfor
  2590.   if fname<>name then
  2591.     retc=-1
  2592.   else
  2593.     retc=strip(retc)
  2594. compile if bkm_tags_between<>''
  2595.     bkm_between=strip(between)
  2596. compile endif
  2597.     bkm_rep_tag=strip(rep_tag)
  2598.     bkm_tag_start=strip(tag_start)
  2599.     bkm_tag_end=strip(tag_end)
  2600.     bkm_end_tag=strip(end_tag)
  2601.     bkm_inv_tag_rep=strip(inv_tag_rep)
  2602. compile if bkm_want_symbols
  2603.     bkm_sym_file=strip(sym_file)
  2604.     getline bkm_symbols,i+1,id
  2605. compile endif
  2606.   endif
  2607. compile if EVERSION < '5.0'
  2608.   if save_command_state then commandtoggle endif
  2609. compile endif
  2610. return retc
  2611.  
  2612. defproc bkm_upd_files(bkm,tag)
  2613.   universal bkm_avail
  2614.   universal bkm_cur_num
  2615.   universal bkm_rep_tag
  2616. compile if bkm_tags_between<>''
  2617.   universal bkm_between
  2618. compile endif
  2619.   universal bkm_tag_start
  2620.   universal bkm_tag_end
  2621.   universal bkm_end_tag
  2622.   universal bkm_inv_tag_rep
  2623. compile if bkm_want_symbols
  2624.   universal bkm_symbols
  2625.   universal bkm_sym_file
  2626. compile endif
  2627. compile if bkm_attr
  2628.   universal bkm_did_bkmattr
  2629. compile endif
  2630. compile if bkm_debugging
  2631.   universal bkm_debug
  2632.   if bkm_debug then call bkm_say("bkm_upd_files("bkm","tag")",0) endif
  2633. compile endif
  2634.   if bkm=-1 then bkm=bkm_cur_num endif
  2635.   getfileid id,'.BKM'
  2636.   if id='' then
  2637.     call bkm_make_bkm()
  2638.     getfileid id,'.BKM'
  2639.     if id='' then
  2640.       call bkm_say("Could not allocate the file '.BKM', support halted.",1)
  2641.       bkm_avail=0
  2642.       return 0
  2643.     endif
  2644.   endif
  2645. compile if EVERSION < '5.0'
  2646.   save_command_state=command_state()
  2647.   if save_command_state then commandtoggle endif
  2648. compile endif
  2649.   for i=1 to id.last
  2650.     getline line,i,id
  2651.     parse value line with fname '==' .
  2652.     if fname=.filename then leave endif
  2653.   endfor
  2654.   bkm_between=strip(tag)
  2655. compile if bkm_want_symbols
  2656.   line=.filename '==' strip(bkm) '||' bkm_between '||' strip(bkm_rep_tag) '||' bkm_tag_start '||' bkm_tag_end '||' bkm_end_tag '||' bkm_inv_tag_rep '||' bkm_sym_file
  2657. compile else
  2658.   line=.filename '==' strip(bkm) '||' bkm_between '||' strip(bkm_rep_tag) '||' bkm_tag_start '||' bkm_tag_end '||' bkm_end_tag '||' bkm_inv_tag_rep
  2659. compile endif
  2660. compile if bkm_attr
  2661.   line=line '||' bkm_did_bkmattr
  2662. compile endif
  2663.   if fname<>.filename then
  2664.     insertline line,1,id
  2665. compile if bkm_want_symbols
  2666.     insertline bkm_symbols,2,id
  2667. compile endif
  2668.   else
  2669.     replaceline line,i,id
  2670. compile if bkm_want_symbols
  2671.     replaceline bkm_symbols,i+1,id
  2672. compile endif
  2673.   endif
  2674.   id.modify=0
  2675. compile if EVERSION < '5.0'
  2676.   if save_command_state then commandtoggle endif
  2677. compile endif
  2678.  
  2679. defproc bkm_make_bkm()
  2680. compile if bkm_debugging
  2681.   universal bkm_debug
  2682.   if bkm_debug then call bkm_say("bkm_make_bkm() called. Current=".filename,0) endif
  2683. compile endif
  2684. /* Now we create the internal work file.                */
  2685.   getfileid curfileid           -- save the current file name
  2686. compile if EPM
  2687.   'xcom edit /n .BKM'           -- Create the file
  2688.   .visible=0
  2689. compile endif
  2690. compile if EOS2
  2691.   'xcom edit /h /q /c .BKM'     -- EOS2
  2692. compile endif
  2693. compile if E3
  2694.   'xcom edit /h /q /n .BKM'     -- E3
  2695. compile endif
  2696.   .filename='.BKM'              -- set the file name
  2697.   activatefile curfileid
  2698.  
  2699. defproc bkm_get_parms(line,flag)
  2700.   universal bkm_tag_start
  2701.   universal bkm_tag_end
  2702.   universal bkm_end_tag
  2703.   universal bkm_rep_tag
  2704.   universal bkm_inv_tag_rep
  2705.   universal bkm_tag_start
  2706.   universal bkm_save_file
  2707. compile if bkm_want_symbols
  2708.   universal bkm_sym_file
  2709. compile endif
  2710. compile if bkm_debugging
  2711.   universal bkm_debug
  2712.   if bkm_debug then call bkm_say("bkm_get_parms("line","flag") called.",0) endif
  2713. compile endif
  2714.   parse value line with delim1 delim2 .
  2715.   if strip(delim1)='*' & strip(delim2)='EBOOKIE' then
  2716.     if flag=1 then
  2717.       x=pos('tag_start=',line)
  2718.       if x then
  2719. ;;      tag_start=substr(line,x+length('tag_start='),1)
  2720. ;;      if strip(tag_start)<>'' then        -- LAM:  If it's not null,
  2721. ;;        bkm_tag_start=strip(tag_start)    -- use result
  2722. ;;      else                                -- but if result is null
  2723. ;;        bkm_tag_start=''                  -- use null ???
  2724. ;;      endif                               -- Then why bother checking if it's null?
  2725.         bkm_tag_start=strip(substr(line,x+length('tag_start='),1))  -- or x+10
  2726.       endif
  2727.       x=pos('tag_end=',line)
  2728.       if x then
  2729. ;;      tag_end=substr(line,x+length('tag_end='),1)
  2730. ;;      if strip(tag_end)<>'' then
  2731. ;;        bkm_tag_end=strip(tag_end)
  2732. ;;      else
  2733. ;;        bkm_tag_end=''
  2734. ;;      endif
  2735.         bkm_tag_end=strip(substr(line,x+length('tag_end='),1))  -- or x+8
  2736.       endif
  2737.       x=pos('end_tag=',line)
  2738.       if x then
  2739. compile if EVERSION >= '5.20'
  2740.         bkm_end_tag=word(substr(line,x+length('end_tag=')),1)  -- or x+8
  2741. compile else
  2742.         end_tag=substr(line,x+length('end_tag='))
  2743.         parse value end_tag with end_tag .
  2744. ;;      if strip(end_tag)<>'' then
  2745. ;;        bkm_end_tag=strip(end_tag)
  2746. ;;      else
  2747. ;;        bkm_end_tag=''
  2748. ;;      endif
  2749.         bkm_end_tag=strip(end_tag)
  2750. compile endif
  2751.       endif
  2752.     endif
  2753.     x=pos('a_2=',line)
  2754.     if x then
  2755.       rep_tag=substr(line,x+length('a_2='))
  2756.       if substr(rep_tag,1,1)<>' ' then
  2757.         parse value rep_tag with bkm_rep_tag .
  2758.       else
  2759.         bkm_rep_tag=''
  2760.       endif
  2761.     endif
  2762.     x=pos('invalid=',line)
  2763.     if x then
  2764.       inv_tag_rep=substr(line,x+length('invalid='))
  2765.       if substr(inv_tag_rep,1,1)<>' ' then
  2766.         parse value inv_tag_rep with bkm_inv_tag_rep .
  2767.       else
  2768.         bkm_inv_tag_rep=''
  2769.       endif
  2770.     endif
  2771. compile if bkm_want_symbols
  2772.     x=pos('symbols=',line)
  2773.     if x then
  2774.       sym_file=substr(line,x+length('symbols='))
  2775.       if substr(sym_file,1,1)<>' ' then
  2776.         parse value sym_file with bkm_sym_file .
  2777.       else
  2778.         bkm_sym_file=''
  2779.       endif
  2780.     endif
  2781. compile endif
  2782.   endif
  2783.   if flag=1 then
  2784.     if bkm_tag_start='' then bkm_tag_start=':' endif
  2785.     if bkm_tag_end='' then bkm_tag_end='.' endif
  2786.     if bkm_end_tag='' then bkm_end_tag=':e' endif
  2787.     if bkm_rep_tag='' then bkm_rep_tag=':p.' endif
  2788.     if bkm_inv_tag_rep='' then
  2789.       bkm_inv_tag_rep='&gml.'
  2790.       if substr(bkm_save_file,1,1)='B' then
  2791.         bkm_inv_tag_rep='&colon.'
  2792.       endif
  2793.     endif
  2794. compile if bkm_want_symbols
  2795.     if bkm_sym_file='' & substr(bkm_save_file,1,1)='B' then
  2796.       parse value bkm_save_file with bkm_sym_file '.' .
  2797.     endif
  2798. compile endif
  2799.   endif
  2800.   if bkm_inv_tag_rep='' then bkm_inv_tag_rep=bkm_tag_start endif
  2801.  
  2802. /* DEFLOAD is called when a new file is read into the   */
  2803. /* ring. In EOS2 and EPM this routine can be here, in   */
  2804. /* E3 it must be included in MYSELECT.E, which calls    */
  2805. /* the procedure bkm_init().                            */
  2806. compile if EVERSION >= '4.12'
  2807. defproc bkm_defload()
  2808.   universal bkm_did_menu
  2809. compile if bkm_debugging
  2810.   universal bkm_debug
  2811.   if bkm_debug then call bkm_say("DEFLOAD called for ".filename,0) endif
  2812. compile endif
  2813. compile if EVERSION > 5
  2814.   if bkm_did_menu <> 1 then call bkm_build_menu() endif
  2815. compile endif
  2816. return bkm_init()
  2817.  
  2818. /* DEFSELECT is called when the file is moved in the    */
  2819. /* topmost position of the ring. This is for EPM and    */
  2820. /* EOS2 only, in E3 this (and more) is done in bkm_init.*/
  2821. defproc bkm_defselect()
  2822. compile if bkm_debugging
  2823.   universal bkm_debug
  2824.   if bkm_debug then call bkm_say("DEFSELECT called for ".filename,0) endif
  2825. compile endif
  2826.   if bkm_find_file(.filename)>0 then
  2827.     call bkm_select()
  2828.   endif
  2829. compile endif
  2830.  
  2831. compile if bkm_attr
  2832. defproc bkm_upd_line_attr(linenum)
  2833.   universal bkm_tag_start
  2834.   universal bkm_tag_end
  2835. compile if EVERSION > '5.16' & EVERSION < '5.50'
  2836.   saveline = .line
  2837.   savecol = .col
  2838. compile endif
  2839.   xline=strip(textline(linenum),'T')
  2840.   first=pos(bkm_tag_start,xline)
  2841.   while first do
  2842.     last=pos(bkm_tag_end,xline,first)
  2843.     if last<first then last=length(xline) endif
  2844.     if last<>first then
  2845. compile if EVERSION >= '5.50'
  2846.       insert_attribute  COLOR_CLASS, 23, 0, -1, last+1, linenum
  2847. compile elseif EVERSION > '5.16'
  2848.       lastlength = length(xline)
  2849.       insert_attribute  COLOR_CLASS, 23, 0, -1, last+1, linenum
  2850.       .col = last+1
  2851.       linenum
  2852.       call shed_attributes()
  2853.       getline xline,linenum
  2854.       if lastlength <> length(xline) then
  2855.         .col = length(xline)
  2856.         oldlevel = .levelofattributesupport
  2857.         .levelofattributesupport = 3
  2858.         delete_char
  2859.         .levelofattributesupport = oldlevel
  2860.       endif
  2861. compile else
  2862.       insert_attribute  COLOR_CLASS, 23, 0, 1, last, linenum
  2863. compile endif
  2864.       insert_attribute  COLOR_CLASS, bkm_attr_colors, 1, -1, first, linenum
  2865.     endif
  2866.     first=pos(bkm_tag_start,xline,last+1)
  2867.   endwhile
  2868. compile if EVERSION > '5.16' & EVERSION < '5.50'
  2869.   saveline
  2870.   .col = savecol
  2871. compile endif
  2872.  
  2873. defproc bkm_add_attr(xcmd)
  2874.   universal bkm_tag_start
  2875.   universal bkm_tag_end
  2876.   universal bkm_did_bkmattr
  2877.   bkm_did_bkmattr=1
  2878.   call psave_pos(OldCursorPos)
  2879.   OldRC = RC
  2880.   display -3
  2881.   saveautosave=.autosave
  2882.   savemodify = .modify
  2883.   .autosave=0
  2884.   0; .col=1
  2885.   TheOffset = -300
  2886.   TheColumn = 1
  2887.   TheLine   = 0
  2888.   TheClass  = ANY_CLASS
  2889.   attribute_action FIND_NEXT_ATTR_SUBOP, TheClass, TheOffset, TheColumn, TheLine
  2890.   while TheClass do
  2891.     attribute_action DELETE_ATTR_SUBOP, TheClass, TheOffset, TheColumn, TheLine
  2892.     TheClass  = ANY_CLASS
  2893.     attribute_action FIND_NEXT_ATTR_SUBOP, TheClass, TheOffset, TheColumn, TheLine
  2894.   endwhile
  2895.   0; .col=1
  2896.   if lowcase(xcmd)<>'off' then
  2897.     "xcom l /"bkm_tag_start"/"
  2898.     while not rc do
  2899.       first=.col
  2900.       fline=.line
  2901.       getline line
  2902.       if pos(substr(line,first+1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') then
  2903.         "xcom l /"bkm_tag_end"/"
  2904.         last=.col
  2905.         lline=.line
  2906. compile if EVERSION >= '5.50'
  2907.         insert_attribute  COLOR_CLASS, 23, 0, -1, last+1, lline
  2908. compile elseif EVERSION > '5.16'
  2909.         getline xline,lline
  2910.         lastlength = length(xline)
  2911.         insert_attribute  COLOR_CLASS, 23, 0, -1, last+1, lline
  2912.         .col = last+1
  2913.         lline
  2914.         call shed_attributes()
  2915.         getline xline,lline
  2916.         if lastlength <> length(xline) then
  2917.           .col = length(xline)
  2918.           oldlevel = .levelofattributesupport
  2919.           .levelofattributesupport = 3
  2920.           delete_char
  2921.           .levelofattributesupport = oldlevel
  2922.         endif
  2923.         .col = last
  2924. compile else
  2925.         insert_attribute  COLOR_CLASS, 23, 0, 1, last, lline
  2926. compile endif
  2927.         insert_attribute  COLOR_CLASS, bkm_attr_colors, 1, -1, first, fline
  2928.       else
  2929.         .col=.col+1
  2930.       endif
  2931.       "xcom l /"bkm_tag_start"/"
  2932.     endwhile
  2933.   else
  2934.     bkm_did_bkmattr=0
  2935.   endif
  2936.   rc = OldRC
  2937.   .autosave=saveautosave
  2938.   .modify = savemodify
  2939.   display 3
  2940.   call prestore_pos(OldCursorPos)
  2941.   call bkm_upd_files(-1,' ')
  2942.  
  2943. ; Thanks to Jason Crawford for the following code
  2944. defproc to_offset_zero()
  2945.    oldline = .line;
  2946.    up; down;
  2947.    .line = oldline;
  2948.  
  2949. ---===shed_attributes===-----------------------------------------
  2950. --
  2951. -- To use shed_attributes(), move the cursor to the character that
  2952. --   is passing its attributes to neighboring characters.
  2953. --
  2954. -- This procedure is handy because it provides a method for
  2955. --  putting an attribute at a positive offset despite the
  2956. --  best efforts of EPM 5.18 to prevent this.
  2957. -- This code will move all the attributes at the beginning
  2958. --   of a character to the previous character, and all
  2959. --   attributes following the attribute to the next character.
  2960.  
  2961. -- This kludge is based on the enhanced behavior of delete_char
  2962. --   when levelofattributesupport has its second bit set.
  2963. --   This behavior moves attributes to adjacent characters
  2964. --   before removing the character.  The cursor must be at
  2965. --   offset 0 for this to happen, otherwise an attribute
  2966. --   will be removed instead.
  2967.  
  2968.  
  2969. defproc shed_attributes()
  2970.   oldcol  = .col;
  2971.   TheText = textline(.line)
  2972.   TheChar = substr(TheText, oldcol, 1);
  2973.   --
  2974.   call to_offset_zero(); -- just to be sure at offset 0
  2975.   oldlevel = .levelofattributesupport;
  2976.   .levelofattributesupport = 3
  2977.      delete_char;
  2978.      keyin TheChar;
  2979.   .levelofattributesupport = oldlevel
  2980.   left;
  2981.  
  2982. compile if EVERSION >= '5.50'
  2983. defc bkm_upd_line_attr =
  2984.   universal bkm_did_bkmattr
  2985.   if bkm_did_bkmattr=1 then
  2986.     oldmod = .modify
  2987.     replaceline textline(.line)
  2988.     call bkm_upd_line_attr(.line)
  2989.     .modify = oldmod
  2990.   endif
  2991. compile endif
  2992. compile endif
  2993.  
  2994. defproc bkm_imbed()
  2995.   universal bkm_config
  2996.   bkm_config = ''
  2997. compile if EVERSION < 5
  2998.  if not command_state() then         -- check for command line
  2999. compile endif
  3000.    line = upcase(textline(.line))
  3001.    parse value line with cmd file ';' .
  3002.    parse value file with file "'" .
  3003.    parse value file with file '"' .
  3004.    if cmd='.IM' | cmd='.SETUP' | cmd='.IM#XMP' | cmd = '.USING' | cmd='.IM$XMP' then
  3005.      If Pos('(',file) then
  3006.        parse value file with '(' file ')' .
  3007.      endif
  3008.      if cmd='.USING' then
  3009.        saveline = .line
  3010.        savecol = .col
  3011.        'xcom L /.config/ca-'
  3012.        if not rc then
  3013.          parse value textline(.line) with . bkm_config .
  3014.        endif
  3015.        saveline
  3016.        .col = savecol
  3017.      endif
  3018.      parse value .filename with fn ft fm
  3019.      if ft<>'' & fm<>'' then
  3020. /* Fix host session id problem, thanks to Pat Lockhart */
  3021.        hsid = ''
  3022.        if pos(':',fn) then
  3023.          parse value fn with hsid ':' fn
  3024.          if hsid <> '' then hsid = hsid||':' endif
  3025.        endif
  3026.        parse value file with ifn ift ifm .
  3027.        If ift='' then ift='SCRIPT' endif
  3028.        If ifm='' then ifm=fm endif
  3029.        ifn = hsid||ifn
  3030.        'edit' ifn ift ifm  -- edit host file
  3031.      else
  3032.        If not pos('.',file) then
  3033.          ext = 'SCR'
  3034.          fm = ''
  3035.          parse value file with file fm .
  3036.          if fm <> '' then ext = substr(fm,1,3) endif
  3037.          file=file||'.'||ext
  3038.        endif
  3039.        path=''
  3040.        If lastpos('\',.filename) then
  3041.          path=substr(.filename,1,lastpos('\',.filename))
  3042.        endif
  3043.        ifile=bkm_findfile(strip(path||file))
  3044.        if ifile='' then ifile=bkm_findfile(file) endif
  3045.        if ifile='' then ifile=strip(path||file) endif   -- new file
  3046.        'edit' ifile
  3047.      endif
  3048. compile if E3
  3049.      call bkm_init()
  3050. compile endif
  3051.    else
  3052.      call bkm_say("Line doesn't contain '.im', '.setup', or '.using'.",0)
  3053.    endif
  3054. compile if EVERSION < 5
  3055.  endif                               -- check for command line
  3056. compile endif
  3057.  
  3058. defproc bkm_rem()
  3059.   universal expand_on
  3060.   universal bkm_rep_tag
  3061.   universal bkm_last_colon
  3062.   universal bkm_last_colon_line
  3063.   universal bkm_tag_start
  3064.   universal bkm_tag_end
  3065.   universal bkm_end_tag
  3066.   if expand_on then                     -- shall we do something?
  3067.     if bkm_rep_tag<>'' then             -- anything defined?
  3068.       if pos(bkm_tag_end,bkm_rep_tag) then      -- find tag-end character
  3069.         char=bkm_tag_end                        -- save it
  3070.         parse value bkm_rep_tag with k (char) . -- remove it from tag
  3071.         k=strip(k)                      -- remove leading and trailing blanks
  3072.       else
  3073.         char=' '                        -- no tag-end character included
  3074.         k=strip(bkm_rep_tag)            -- get tag
  3075.       endif
  3076.       bkm_last_colon=.col               -- save position of tag-start
  3077.       bkm_last_colon_line=.line         -- save line number
  3078.       keyin k                           -- type characters
  3079.       call bkm_expansion(char)          -- expand it if a tag
  3080.       bkm_last_colon=0                  -- reset last colon position
  3081.     endif
  3082.   endif
  3083.  
  3084. compile if bkm_help_support
  3085. defproc bkm_help(aorc)
  3086.   universal bkm_save_file
  3087.   universal bkm_tag_start
  3088. compile if bkm_help_reference           /* temple */
  3089.   if aorc = 'a' then
  3090.     call bkm_ref()
  3091.     return 0
  3092.   endif
  3093. compile endif
  3094.   if bkm_find_file(.filename)=0 then
  3095.     call bkm_say("Support is not active for this file",0)
  3096.   else
  3097.     parse value bkm_save_file with help_file hrest
  3098.     Parse Value help_file with s_help_file '.' .
  3099.     s_help_file=s_help_file||'.HLP'
  3100.     loop
  3101.       Parse Value help_file with help_file '.' .
  3102.       help_file=help_file||'.HLP'
  3103.       getfileid curfile
  3104.       getfileid id,help_file
  3105.       if id='' then
  3106.         help_file=bkm_findfile(help_file)
  3107.         if help_file<>'' then
  3108. compile if EPM
  3109.           'xcom edit' help_file
  3110.           .visible=0
  3111. compile else
  3112.           'xcom edit /h /q' help_file
  3113. compile endif
  3114.           activatefile curfile
  3115.           if rc then
  3116.             call bkm_say("Unable to load the file" help_file", out of storage",0)
  3117.           endif
  3118.         endif
  3119.         getfileid id,help_file
  3120.       endif
  3121.       if id <> '' then leave endif
  3122.       if hrest = '' then leave endif
  3123.       parse value hrest with help_file hrest
  3124.     endloop
  3125.     if id='' then
  3126.       call bkm_say("Unable to find the file" s_help_file", support not available",0)
  3127.     else
  3128.       getline line,.line
  3129.       fcol=lastpos(' ',line,.col)+1
  3130.       lcol=pos(' ',line||' ',.col)-1
  3131.       xword=strip(substr(line,fcol,lcol-fcol+1))
  3132.       if Substr(xword,1,1) <> '.' then
  3133.         parse value xword with xword '.' .
  3134.       endif
  3135.       if Substr(xword,1,1) <> '=' then
  3136.         parse value xword with xword '=' .
  3137.       endif
  3138.       done=0
  3139.       for i = 1 to id.last                  -- loop over help file
  3140.         getline helpline,i,id               -- no, get line from index
  3141.         if substr(helpline,1,1)=' ' then iterate endif
  3142.         parse value helpline with attribute .
  3143.         parse value attribute with attribute '\' .
  3144.         parse value attribute with attribute '=' .
  3145.         if upcase(attribute)=upcase(xword) then
  3146.           done=1
  3147.           getfileid hlpfile,'.HLP'
  3148.           if hlpfile <> '' then
  3149.             activatefile hlpfile
  3150.             .modify=0
  3151.             'quit'
  3152.           endif
  3153.           'xcom edit /q /n .HLP'
  3154.           sayerror 0
  3155.           'ma 1 80 1'
  3156.           join_after_wrap=0
  3157.           for j=i to id.last
  3158.             getline helpline,j,id
  3159.             if substr(helpline,1,1)<>' ' then
  3160.               parse value helpline with attribute .
  3161.               parse value attribute with attribute '\' .
  3162.               parse value attribute with attribute '=' .
  3163.               if upcase(attribute)<>upcase(xword) then leave endif
  3164.               If j>i then
  3165.                 insert
  3166.                 insert
  3167.                 insert
  3168.                 down
  3169.                 down
  3170.                 down
  3171.                 begin_line
  3172.               endif
  3173.             endif
  3174.             helpline=strip(helpline)
  3175.             getline line
  3176.             if strip(line)<>'' then helpline=' 'helpline endif
  3177.             loop
  3178.               if not pos('\',helpline) then leave endif
  3179.               parse value helpline with xleft '\' helpline
  3180.               keyin xleft
  3181.               insert
  3182.               down
  3183.               begin_line
  3184.             endloop
  3185.             keyin helpline
  3186.           endfor
  3187.           .modify=0
  3188.           'top'
  3189.           leave
  3190.         endif
  3191.       endfor
  3192.       if not done then
  3193.         call bkm_say("No help for" xword "found.",0)
  3194.       endif
  3195.     endif
  3196.   endif
  3197. compile endif
  3198.  
  3199. compile if bkm_idx_supp
  3200. defproc bkm_idx_make()
  3201.   universal bkm_avail
  3202.   if bkm_avail=1 & bkm_find_file(.filename)>0 Then
  3203.     type=marktype()
  3204.     if type='' then
  3205.       fline=.line
  3206.       lline=.line
  3207.       fcol=.col
  3208.       lcol=.col
  3209.     else
  3210.       getmark fline, lline, fcol, lcol
  3211.     endif
  3212.     if type='LINE' then
  3213.       call bkm_say("Line mark invalid, must be block mark or not marked at all.",0)
  3214.     else
  3215.       if fline<>lline then
  3216.         call bkm_say("The marked block must not span lines.",0)
  3217.       else
  3218.         getline line,fline
  3219.         if fcol=lcol then
  3220.           fcol=lastpos(' ',' '||line,fcol)
  3221.           if substr(line,fcol,1)=' ' then fcol=fcol+1 endif
  3222.           lcol=pos(' ',line||' ',lcol)-1
  3223.         endif
  3224.         xblock=strip(substr(line,fcol,lcol-fcol+1))
  3225.         loop
  3226.           x=pos(':',xblock)
  3227.           if not x then leave endif
  3228.           y=pos('.',xblock,x)
  3229.           if not y then leave endif
  3230. compile if EVERSION >= '5.20'
  3231.           xblock=delstr(xblock,x,y-x+1)
  3232. compile else
  3233.           if x=1 then
  3234.             xblock=substr(xblock,y+1)
  3235.           else
  3236.             xblock=substr(xblock,1,x-1)||substr(xblock,y+1)
  3237.           endif
  3238. compile endif
  3239.         endloop
  3240.         loop
  3241.           x=verify(xblock, ',"''', 'M')  -- LAM:  Handles , " and ' in one loop.
  3242.           if not x then leave endif
  3243. compile if EVERSION >= '5.20'
  3244.           xblock=delstr(xblock,x,1)
  3245. compile else
  3246.           if x=1 then
  3247.             xblock=substr(xblock,2)
  3248.           else
  3249.             xblock=substr(xblock,1,x-1)||substr(xblock,x+1)
  3250.           endif
  3251. compile endif
  3252.         endloop
  3253.         if substr(xblock,1,1)='(' then  -- LAM: Could delete all parens by adding '()' to verify() string above...
  3254.           xblock=substr(xblock,2)
  3255. compile if EVERSION >= '5.20'
  3256.           if rightstr(xblock,1)=')' then xblock=leftstr(xblock,length(xblock)-1) endif
  3257. compile else
  3258.           if substr(xblock,length(xblock),1)=')' then xblock=substr(xblock,1,length(xblock)-1) endif
  3259. compile endif
  3260.         endif
  3261.         xblock=strip(xblock)
  3262. compile if EVERSION >= '5.20'
  3263.         if rightstr(xblock,1)='.' then
  3264. compile else
  3265.         if substr(xblock,length(xblock),1)='.' then
  3266. compile endif
  3267.           x=lastpos('&',xblock)
  3268.           if x then
  3269.             if pos(' ',xblock,x) then
  3270.               xblock=substr(xblock,1,length(xblock)-1)
  3271.             endif
  3272.           else
  3273.             xblock=substr(xblock,1,length(xblock)-1)
  3274.           endif
  3275.         endif
  3276.         x=pos('.',xblock)
  3277.         if x then
  3278.           if not lastpos('&',xblock,x) then
  3279.             if not lastpos(' ',xblock) then
  3280.               xblock=substr(xblock,x+1)
  3281.             endif
  3282.           endif
  3283.         endif
  3284. compile if bkm_keep_index_cases
  3285.         yblock=strip(xblock)
  3286.         xblock=''
  3287.         loop
  3288.           parse value yblock with xword yblock
  3289.           if xword='' then leave endif
  3290.           zword=lowcase(xword)
  3291.           if xword=upcase(xword) then
  3292.             xblock=xblock xword
  3293.           else
  3294.             xblock=xblock zword
  3295.           endif
  3296.         endloop
  3297. compile endif
  3298.         xblock=strip(xblock)
  3299.         insertline ".***",fline+1
  3300.         insertline ":i1."xblock,fline+2
  3301. compile if EVERSION >= '5.20'
  3302.         for i=2 to words(xblock)
  3303.           insertline ":i1." || subword(xblock,i) || ", " || subword(xblock,1,i-1),fline+i+1
  3304.         endfor
  3305.         insertline ".***",fline+i+1
  3306. compile else
  3307.         j=1
  3308.         for i=3 to 99
  3309.           x=0
  3310.           for k=1 to j
  3311.             x=pos(' ',xblock,x+1)
  3312.           endfor
  3313.           if not x then leave endif
  3314.           insertline ":i1." || substr(xblock,x+1) || ", " || substr(xblock,1,x),fline+i
  3315.           j=j+1
  3316.         endfor
  3317.         insertline ".***",fline+i
  3318. compile endif
  3319.         unmark
  3320.       endif
  3321.     endif
  3322.   endif
  3323. compile endif
  3324.  
  3325. compile if bkm_help_reference           /* temple */
  3326. defproc bkm_ref()
  3327.   universal bkm_tag_start
  3328.   universal bkm_tag_end
  3329.   universal bkm_save_file
  3330.   if bkm_find_file(.filename)=0 then
  3331.     call bkm_say("Support is not active for this file",0)
  3332.   else
  3333.     parse value bkm_save_file with help_file hrest
  3334.     parse value help_file with s_help_file '.' .
  3335.     s_help_file=s_help_file||'.INF'
  3336.     xfile = ''
  3337.     loop
  3338.       Parse Value help_file with help_file '.' .
  3339.       help_file=help_file||'.INF'
  3340.       findfile xfile, help_file, 'BOOKSHELF'
  3341. ;;    if rc then findfile xfile, help_file, 'EPATH' endif  -- LAM:  EPM uses EPMPATH, not EPATH, and
  3342.       if rc then findfile xfile, help_file, '', 'D' endif  -- this searches EPMPATH as well as DPATH
  3343.       if not rc then leave endif
  3344.       if hrest = '' then leave endif
  3345.       parse value hrest with help_file hrest
  3346.     endloop
  3347.     if xfile = '' then
  3348.        call bkm_say("Help file" s_help_file "not found.",0)
  3349.        return 0
  3350.     endif
  3351.     getline line,.line
  3352.     fcol=lastpos(' ',line,.col)+1
  3353.     lcol=pos(' ',line||' ',.col)-1
  3354.     xword=strip(substr(line,fcol,lcol-fcol+1))
  3355.     if Substr(xword,1,1) = bkm_tag_start then
  3356.       xword = substr(xword,2)
  3357.     endif
  3358.     if pos(bkm_tag_end,xword) then
  3359.        xword = substr(xword,1,pos(bkm_tag_end,xword)-1)
  3360.     endif
  3361.     if Substr(xword,1,1) <> '=' then
  3362.       parse value xword with xword '=' .
  3363.     endif
  3364.     'VIEW' xfile xword
  3365.   endif
  3366. compile endif
  3367.  
  3368. compile if EPM
  3369. defproc bkm_build_menu()
  3370.   universal defaultmenu
  3371.   universal activemenu
  3372.   universal bkm_did_menu
  3373.  compile if EVERSION >= 5.20
  3374.    universal activeaccel
  3375.  compile endif
  3376. compile if KEEP_HELP_AT_RIGHT
  3377.   deletemenu defaultmenu, 6, 0, 0  -- delete the existing Help menu (we want it to stay at the right)
  3378. compile endif
  3379.   grey = 16384
  3380.   buildsubmenu defaultmenu, 21,      'E'TILDE_CHAR'bookie',    ' ',           0,0
  3381.   buildmenuitem defaultmenu,21, 2101, '~Bookie on',            'bookie on',   0,0
  3382.   buildmenuitem defaultmenu,21, 2102, 'Bookie ~off',           'bookie off',  0,0
  3383.   buildmenuitem defaultmenu,21, 2103, \0,                      '',            4,0
  3384. compile if bkm_attr
  3385.   buildmenuitem defaultmenu,21, 2104, '~Attribute on',         'bkmattr on',  0,0
  3386.   buildmenuitem defaultmenu,21, 2105, 'A~ttribute off',        'bkmattr off', 0,0
  3387. compile if EVERSION >= '5.50'
  3388.   buildmenuitem defaultmenu,21, 2120, '~Fixup attributes',     'bkm_upd_line_attr', 0,0
  3389. compile endif
  3390. compile else
  3391.   buildmenuitem defaultmenu,21, 2104, '~Attribute on',         'bkmattr on',  0,grey
  3392.   buildmenuitem defaultmenu,21, 2105, 'A~ttribute off',        'bkmattr off', 0,grey
  3393. compile if EVERSION >= '5.50'
  3394.   buildmenuitem defaultmenu,21, 2120, '~Fixup attributes',     'bkm_upd_line_attr', 0,grey
  3395. compile endif
  3396. compile endif
  3397.   buildmenuitem defaultmenu,21, 2106, \0,                      '',            4,0
  3398. compile if bkm_want_symbols
  3399.   buildmenuitem defaultmenu,21, 2107, '~Symbols all/mark',     'bkmsym all',  0,0
  3400. compile else
  3401.   buildmenuitem defaultmenu,21, 2107, '~Symbols all/mark',     'bkmsym all',  0,grey
  3402. compile endif
  3403.   buildmenuitem defaultmenu,21, 2108, \0,                      '',            4,0
  3404. compile if bkm_debugging
  3405.   buildmenuitem defaultmenu,21, 2109, '~Debug on',             'bkmdebug on', 0,0
  3406.   buildmenuitem defaultmenu,21, 2110, 'D~ebug off',            'bkmdebug off',0,0
  3407.   buildmenuitem defaultmenu,21, 2111, 'De~bug on+echo',        'bkmdebug t'  ,0,0
  3408.   buildmenuitem defaultmenu,21, 2112, 'Debug dis~play',        'bkmdebug d'  ,0,0
  3409. compile else
  3410.   buildmenuitem defaultmenu,21, 2109, '~Debug on',             'bkmdebug on' ,0,grey
  3411.   buildmenuitem defaultmenu,21, 2110, 'D~ebug off',            'bkmdebug off',0,grey
  3412.   buildmenuitem defaultmenu,21, 2111, 'De~bug on+echo',        'bkmdebug t'  ,0,grey
  3413.   buildmenuitem defaultmenu,21, 2112, 'Debug dis~play',        'bkmdebug d'  ,0,grey
  3414. compile endif
  3415.   buildmenuitem defaultmenu,21, 2113, \0,                      '',            4,0
  3416.   buildmenuitem defaultmenu,21, 2114, 'Edit ~imbed'\9'a_1',    'bkmimbed',    0,0
  3417.   buildmenuitem defaultmenu,21, 2115, 'Insert default ~tag'\9'a_2', 'bkmrem', 0,0
  3418. compile if bkm_help_support
  3419.   buildmenuitem defaultmenu,21, 2116, '~Help for tag'\9'a_h',   'bkmhelp',    0,0
  3420. compile else
  3421.   buildmenuitem defaultmenu,21, 2116, '~Help for tag'\9'a_h',   'bkmhelp',    0,grey
  3422. compile endif
  3423. compile if bkm_idx_supp
  3424.   buildmenuitem defaultmenu,21, 2118, 'I~ndex word/mark'\9'a_i', 'bkmidx',    0,0
  3425. compile else
  3426.   buildmenuitem defaultmenu,21, 2118, 'I~ndex word/mark'\9'a_i', 'bkmidx',    0,grey
  3427. compile endif
  3428.   buildmenuitem defaultmenu,21, 2119, 'Vie~w documentation' ,   'view ebookie',    0,0
  3429. compile if KEEP_HELP_AT_RIGHT
  3430.  compile if EVERSION >= '5.20'  -- We know that OS/2 must be over 1.2
  3431.   call add_help_menu(defaultmenu, 1)  -- rebuild the help menu
  3432.  compile else
  3433.   call add_help_menu(defaultmenu, dos_version()>=1020)  -- rebuild the help menu
  3434.  compile endif
  3435. compile endif
  3436.   if activemenu = defaultmenu then     -- If this is the active menu, then
  3437.      showmenu defaultmenu              -- activate the above changes
  3438.   endif
  3439. compile if EVERSION >= 5.20 & TILDE_CHAR <> ''
  3440.    buildacceltable activeaccel, 'dokey a+B', AF_CHAR+AF_ALT,                  66, 2191  -- a+B
  3441.    buildacceltable activeaccel, 'dokey a+B', AF_CHAR+AF_ALT,                  98, 2192  -- a+b
  3442.    activateacceltable  activeaccel
  3443. compile endif
  3444.   bkm_did_menu = 1
  3445. compile endif  -- EPM
  3446.