%  file: sgml.sl
%
%  Author:      Guido Gonzato, guido@ibogeo.df.unibo.it
%  Version:     beta 0.9.9 - pretty functional; implements everything that 
%               is described in the sgml-tools 1.0.7 user guide, apart from
%               a few special characters.
%  Date:	19 May 1999
%
% Now, a few routines to make life easier

% read tex_insert_quote


!if (is_defined ("tex_ldots")) () = evalfile ("texcom");

define sgml_read_key (msg)
{
  variable key;
  !if (input_pending (3)) flush (msg);
  tolower (getkey ());
}

define sgml_insert_tags (tag1, tag2)
{
  insert (tag1);
  push_spot ();
  insert (tag2);
  pop_spot ();
}

define sgml_insert_pair_around_region (left, right)
{
   check_region(1);
   exchange_point_and_mark();
   insert(left);
   exchange_point_and_mark();
   insert(right);
   pop_spot();
   pop_mark_0 ();
}

define sgml_paragraph_separator ()
{
  bol ();
  skip_white ();
  eolp () or ffind_char ('>') or ffind_char ('<');
}

define sgml_idx()		% ^CMI
{
  sgml_insert_pair_around_region("<idx>", "<cdx>");
}

define sgml_ridx()		% ^CMR
{
  sgml_insert_pair_around_region("<ridx>", "<rcdx>");
}

define sgml_bskip_tag ()	% ^C^B
{
  %ide_set_bookmark ();
  () = bsearch_char ('<');
}  

define sgml_figure ()		% ^CMF
{
  insert ("<figure LOC=htb>\n");
  insert ("  <eps file=\"");
  push_spot ();
  insert ("\" height=\"5cm\">\n");
  insert ("  <img src=\"\">\n");
  insert ("    <caption>\n");
  insert ("    <label id=\"\">\n\n");
  insert ("    </caption>\n");
  insert ("</figure>\n");
  pop_spot ();
}

define sgml_table ()		% ^CMT
{
  insert ("<table LOC=htb>\n");
  insert ("<tabular CA=\"");
  push_spot ();
  insert ("lrc\">\n");
  insert ("<hline>\n");
  insert ("<!-- item | item | ... @ -->\n");
  insert ("<hline>\n");
  insert ("</tabular>\n");
  insert ("  <caption>\n");
  insert ("  <label id=\"\">\n\n");
  insert ("  </caption>\n");
  insert ("</table>\n");
  pop_spot ();
}

define sgml_comment ()		% ESC ;
{
  sgml_insert_pair_around_region ("<!-- ", "-->");
}  

define sgml_skip_tag ()		% ^C^F
{
  !if (fsearch_char ('>')) return;
  go_right_1 ();
  go_right_1 ();
}

define sgml_template ()		% ^C^M
{
  insert ("<!doctype linuxdoc system>\n<article>\n\n<title> ");
  push_spot ();
  insert ("\n\n<author> \n\n<date> \n\n<abstract>\n\n</abstract>\n\n");
  insert ("<toc>\n\n<sect>\n\n<p>\n\n\n</article>");
  pop_spot ();
}

define sgml_keymap_c ()
{
  variable ch;
  
  flush ("Special characters:  & \\ @ © ° $ </ > { _ < # % } ~ |");
  
  ch = getkey ();
  
  switch (ch)
    { case '&': insert ("&amp;"); 	}
    { case '\\' : insert ("&bsol;");	}
    { case '@' : insert ("&commat;");	}
    { case '©' : insert ("&copy;");	}
    { case '°' : insert ("&deg;");	}
    { case '$' : insert ("&dollar;");	}
    { case '/' : insert ("&etago;");	}
    { case '>' : insert ("&gt;");	}
    { case '{' : insert ("&lcub;");	}
    { case '_' : insert ("&lowbar;");	}
    { case '<' : insert ("&lt;");	}
    { case '#' : insert ("&num;");	}
    { case '%' : insert ("&percnt;");	}
    { case '}' : insert ("&rcub;");	}
    { case '~' : insert ("&tilde;");	}
    { case '|' : insert ("&verbar;");	}
  
  flush ("");
  
}

define sgml_keymap_e ()
{
  variable ch;
  
  flush ("Environments:  Code  Quote  Verbatim");
  
  ch = getkey ();
  
  switch (ch)
    { case 'c': sgml_insert_tags ("<code>\n", "\n</code>\n"); }
    { case 'q': sgml_insert_tags ("<quote>\n", "\n</quote>\n"); }
    { case 'v': sgml_insert_tags ("<tscreen><verb>\n", 
				  "\n</verb></tscreen>\n"); }
  
  flush ("");
}

define sgml_keymap_f ()
{
  variable ch;
  
  flush ("Fonts:  Bold  File  Italics  Typewriter");
  
  ch = getkey ();
  
  switch (ch)
    { case 'b': sgml_insert_tags ("<bf>", "</bf>"); }
    { case 'f': sgml_insert_tags ("<file>", "</file>"); }
    { case 'i': sgml_insert_tags ("<em>", "</em>"); }
    { case 't': sgml_insert_tags ("<tt>", "</tt>"); }

  flush ("");
}

define sgml_keymap_l ()
{
  variable ch;
  
  flush ("Lists:  Description  Enumerate  Item  iteMize  Tag");
  
  ch = getkey ();
  
  switch (ch)
    { case 'd': sgml_insert_tags ("<description>\n\n<tag/ ", 
				  "\n\n</description>\n"); }
    { case 'e': sgml_insert_tags ("<enum>\n\n<item> ", 
				  "\n\n</enum>\n"); }
    { case 'i': insert ("<item> "); }
    { case 'm': sgml_insert_tags ("<itemize>\n\n<item> ", 
				  "\n\n</itemize>\n"); }
    { case 't': insert ("<tag/ "); }
  
  flush ("");
}

define sgml_keymap_m ()
{
  variable ch;
  
  flush ("Misc:  Figure  Idx  temPlate  Ridx  Table");
  
  ch = getkey ();
  
  switch (ch)
    { case 'f': sgml_figure (); }
    { case 'i': sgml_idx ();    }
    { case 'p': sgml_template ();    }
    { case 'r': sgml_ridx ();   }
    { case 't': sgml_table ();  }

  flush ("");
}

define sgml_keymap_r ()
{
  variable ch;
  
  flush ("Cross refs:  Label  Ref");
  
  ch = getkey ();
  
  switch (ch)
    { case 'l': sgml_insert_tags ("<label id=\"", "\">"); }
    { case 'r': sgml_insert_tags ("<ref id=\"", "\" name=\"\">"); }
  
  flush ("");
}

define sgml_keymap_s ()
{
  variable ch;
  
  flush ("Sections:  Sect  sect1  sect2  sect3  sect4");
  
  ch = getkey ();
  
  switch (ch)
    { case 's': sgml_insert_tags ("<sect> ", "\n\n<p>\n\n"); }
    { case '1': sgml_insert_tags ("<sect1> ", "\n\n<p>\n\n"); }
    { case '2': sgml_insert_tags ("<sect2> ", "\n\n<p>\n\n"); }
    { case '3': sgml_insert_tags ("<sect3> ", "\n\n<p>\n\n"); }
    { case '4': sgml_insert_tags ("<sect4> ", "\n\n<p>\n\n"); }
	  
  flush ("");
}

define sgml_keymap_u ()
{
  variable ch;
  
  flush ("URLs:  Htmlurl  Url url");
  
  ch = getkey ();
  
  switch (ch)
    { case 'h': sgml_insert_tags ("<htmlurl url=\"", "\" name=\"\">"); }
    { case 'u': sgml_insert_tags ("<url url=\"", "\">"); }

  flush ("");
}

define sgml_handle_lt()
{
  variable ch;
  ch = getkey();
  if (ch == '/')
    insert("&etago;");
  else {
    ungetkey();
    insert("&lt;");
  }
}  

% Key bindings

define sgml_keymap ()
{
  switch (sgml_read_key 
("Characters  Environments  Fonts  Lists  cRoss-refs  Sections  Urls  Misc"))
    { case 2: sgml_bskip_tag ();	}		%  ^B
    { case 6: sgml_skip_tag ();		}		%  ^F
    { case '#' : insert("&num;");	}
    { case '$' : insert("&dollar;");	}
    { case '&' : insert("&amp;");	}
    { case '-' : insert("&shy;");	}
    { case '<' : sgml_handle_lt();	}
    { case '>' : insert("&gt;");	}
    { case '\\': insert("&bsol;");	}
    { case '{' : insert ("&lcub;");	}
    { case '|' : insert ("&verbar;");	}
    { case '}' : insert ("&rcub;");	}
    { case '~' : insert("&tilde;");	}
% more to follow...
    { case ';': sgml_comment ();  }
    { case 'c': sgml_keymap_c (); }
    { case 'e': sgml_keymap_e (); }
    { case 'f': sgml_keymap_f (); }
    { case 'l': sgml_keymap_l (); }
    { case 'r': sgml_keymap_r (); }
    { case 's': sgml_keymap_s (); }
    { case 'u': sgml_keymap_u (); }
    { case 'm': sgml_keymap_m (); }
%     {
%       ungetkey (());
%       sgml_quoted_insert ();
%     }

  flush ("");
}

$1 = "sgml";
!if (keymap_p ($1)) make_keymap ($1);
undefinekey ("^C", $1);
definekey("sgml_keymap", "^C", $1);
undefinekey ("\e;", $1);
definekey ("sgml_comment", "\e;", $1);
definekey ("tex_insert_quote", "\"", $1);
definekey ("tex_insert_quote", "'", $1);
create_syntax_table ($1);
set_syntax_flags ($1, 8);

% defining keywords is not necessary, since all the highlighting is
% done by the second and third define_syntax (). Rough, but fairly nice.

define_syntax ("\"([{<", "\")]}>", '(', $1);
define_syntax ('<', '\\', $1);
define_syntax ('&', '\\', $1);
define_syntax ("0-9A-Za-z>/!", 'w', $1);
define_syntax ("<>", '<', $1);
define_syntax ("<!-", "-->", '%', $1);

define sgml_mode ()
{
  variable sgml = "sgml";

  set_mode(sgml, 1); % wrap mode
  set_buffer_hook ("par_sep", "sgml_paragraph_separator");
  use_syntax_table (sgml);
  use_keymap (sgml);
  run_mode_hooks ("sgml_mode_hook");
}

% --- End of file sgml.sl ---
