[Jed-users-l] the lout mode is here

Robert S. Bernstein rs at bernstein.providence.ri.us
Wed Feb 24 22:59:13 UTC 2010


Here is the lout mode unearthed by George Bruin's indefatigable
efforts.


-- 
Bob Bernstein

  IMPORTANT: This email is intended for the use of the individual
  addressee(s) named above and may contain information that is
  confidential, privileged or unsuitable for overly sensitive persons
  with no sense of humor or irrational metaphysical beliefs.
-------------- next part --------------
% This is a JED mode for the `lout' text processor. JED is both: A wonderfull, small,
% fast, extensible and portable editor, and the initials of its author John E. Davis.
% Lout is a compact, powerfull and easy to use document formatting system in the tradition
% of troff and TeX. It was written by Jeffrey H. Kingston.
% 
% jed_mode is written by Olaf Rogalsky, (olaf.rogalsky at theorie1.physik.uni-erlangen.de)
% No license, do whatever you like with it.
% Version 0.2b, very loosly based on latex_mode
%
% If YOU have wishes, improvements or find a bug, please don't hesitate to write
% me an email, I realy like to hear from YOU!
%
% Installation: (sorry, for unix like systems only - I don't have M$-Windoof)
%   user> su
%   root# JED_ROOT=$(jed -batch -n -f 'flush(JED_ROOT)'|tail -1) # ksh, bash, etc
%   root# cp lout.sl $JED_ROOT/lib
%   root# jed -batch -n -f 'byte_compile_file(JED_ROOT+"/lib/lout.sl",0)'
%   root# jed -batch -n -f 'evalfile(JED_ROOT+"/lib/lout.sl"); lout_mode();'
%   root# chmod 644 $JED_ROOT/lib/lout.*
%   For system wide configuration add the following four lines to
%   $JED_ROOT/lib/default.sl, or else add them to $HOME/.jedrc:
%      autoload("lout_mode","lout.sl");
%      add_mode_for_extension ("lout","lout");
%      add_mode_for_extension ("lout","lt");
%      add_mode_for_extension ("lout","ld");
%   
% Some remarks:
%   *  Lout_mode is unaware of equations, tables, diagrams and graphs.
%   *  You can add your own symbols to the autocompleter of lout_mode with the function
%      "lout_add_completion_symbol". Look at the end of this file for an example.
%   *  The lout_mode keymap is defined at the end of this file.
%   *  lout_mode can define its own color-scheme, if the environment variable
%      JED_XTERM_HIGHLIGHT is set. Of course this is only usefull if you are
%      using a (modern) xterm.
%   *  If HAS_DFA_SYNTAX is defined, a few addtional colors will be defined.
%      In the best of all worlds this would not be necessary, because there the
%      colours were already defined by the current color-scheme.
%   *  The code is exuberantly documented. Look out for the string `fixme' for
%      obvious and known bugs^H^H^H^Hcuriosities.
%   *  Functions which are thought to be only usefull in lout_mode start with
%      the prefix `lout_' and are lowercase.
%   *  Global custom variables start with the prefix `LOUT_' and are uppercase.
%   *  No bugs, everything is intentional :-).
%   *  Thank you John, thank you Jeff!

provide ("lout");
require ("compile");
compile_add_compiler ("lout", "^\\([^ :]+\\):\\(\\d+\\):\\(\\d+\\):");

%!%+
%\variable{LOUT_IGNORE_COMMENT}
%\synopsis{LOUT_IGNORE_COMMENT}
%\description
% If true, any line containing a comment does not delimit a paragraph.
%\seealso{lout_paragraph_separator, lout_mode}
%!%-
custom_variable ("LOUT_IGNORE_COMMENT", 0);


%!%+
%\variable{LOUT_INDENTATION}
%\usage{Integer_Type LOUT_INDENTATION}
%\description
% Number of spaces to be added or removed while indenting.
%\seealso{indent_line, lout_ident_line}
%!%-
custom_variable ("LOUT_INDENTATION", 2);

%!%+
%\variable{LOUT_DEFAULT_FONT}
%\usage{String_Type LOUT_DEFAULT_FONT}
%\description
% Holds the default font of the document. Meaningfull
% values among others are "avantgarde", "bookman", "chancery",
% "courier", "helvetica", "schoolbook", "palatino", "symbol",
% "times", "dingbats".
%\seealso{LOUT_DEFAULT_FONT_SIZE, LOUT_DEFAULT_FONT_FACE, lout_mode}
%!%-
custom_variable ("LOUT_DEFAULT_FONT", "times");

%!%+
%\variable{LOUT_DEFAULT_FONT_SIZE}
%\usage{String_Type LOUT_DEFAULT_FONT_SIZE}
%\description
% Holds the default font size of the document. Meaningfull
% values among others are "10p", "12p".
%\seealso{LOUT_DEFAULT_FONT, LOUT_DEFAULT_FONT_FACE, lout_mode}
%!%-
custom_variable ("LOUT_DEFAULT_FONT_SIZE", "12p");

%!%+
%\variable{LOUT_DEFAULT_FONT_FACE}
%\usage{String_Type LOUT_DEFAULT_FONT_FACE}
%\description
% Holds the default font face of the document. Meaningfull
% values among others are "base", "slope", "bold", "boldslope".
%\seealso{LOUT_DEFAULT_FONT, LOUT_DEFAULT_FONT_SIZE, lout_mode}
%!%-
custom_variable ("LOUT_DEFAULT_FONT_FACE", "base");


%!%+
%\variable{LOUT_DEFAULT_DOCUMENT}
%\usage{String_Type LOUT_DEFAULT_DOCUMENT}
%\description
% Holds the default font face of the document. Meaningfull
% values among others are "document", "report", "book", "slides",
% "illustration".
%\seealso{lout_insert_document, lout_mode}
%!%-
custom_variable ("LOUT_DEFAULT_DOCUMENT", "document");

create_syntax_table ("lout");
%define_syntax ("|/^&{}", ',', "lout");          % delimiters, not needed!
define_syntax ("#", "", '%', "lout");            % comments
define_syntax ("{", "}", '(', "lout");           % matching pairs, @Begin, at End isn't possible :-(
define_syntax ('"', '"', "lout");                % strings
define_syntax ("|/^&", '+', "lout");             % operators
define_syntax ("a-zA-Z??-????-????-??", 'w', "lout");  % words fixme: I still don't grasp all consequences
                                                 %              of 'w' JED, please document 'w'

% This is a compromise: '@' actually isn't the quote character,
% but TeX style keyword high lightening is appropriate
define_syntax ('@', '\\', "lout");
set_syntax_flags ("lout", 0x8);


#ifdef HAS_DFA_SYNTAX
% fixme: this is a hack for newer xterms, which can do more than colors
if (NULL != getenv ("JED_XTERM_HIGHLIGHT")) {
  % define our own color-scheme
  set_color_esc ("menu",       "\e[0m\e[97m\e[44m"); % white/blue
  set_color_esc ("normal",     "\e[0m\e[97m\e[40m"); % white/black
  set_color_esc ("status",     "\e[0m\e[93m\e[44m"); % yellow/blue
  set_color_esc ("region",     "\e[0m\e[93m\e[44m"); % yellow/blue
  set_color_esc ("operator",   "\e[0m\e[32m\e[40m"); % green/black
  set_color_esc ("number",     "\e[0m\e[93m\e[40m"); % yellow/black
  set_color_esc ("comment",    "\e[0m\e[96m\e[40m"); % brightcyan/black
  set_color_esc ("string",     "\e[0m\e[92m\e[40m"); % brightgreen/black
  set_color_esc ("delimiter",  "\e[0m\e[97m\e[40m"); % white/black
  set_color_esc ("preprocess", "\e[0m\e[35m\e[40m"); % magenta/black
  set_color_esc ("message",    "\e[0m\e[93m\e[40m"); % yellow/black
  set_color_esc ("error",      "\e[0m\e[91m\e[40m"); % brightred/black
  set_color_esc ("...",        "\e[0m\e[31m\e[40m"); % red/black
  set_color_esc ("menu_char",  "\e[0m\e[93m\e[44m"); % yellow/blue
  set_color_esc ("menu",       "\e[0m\e[37m\e[44m"); % lightgray/blue
  set_color_esc ("menu_popup", "\e[0m\e[37m\e[44m"); % lightgray/blue
  set_color_esc ("menu_shadow","\e[0m\e[34m\e[40m"); % blue/black
  set_color_esc ("menu_selection", "\e[0m\e[97m\e[46m"); % white/cyan
  set_color_esc ("menu_selection_char", "\e[0m\e[93m\e[46m"); % yellow/cyan
  
  set_color ("cursor", "black", "red");
  set_color ("cursorovr", "black", "red");

  set_color_esc ("keyword",  "\e[0m\e[91m\e[40m");      % brightred/black
  set_color_esc ("keyword1", "\e[0m\e[32m\e[40m");      % green/black
  set_color_esc ("keyword2", "\e[0m\e[5m\e[97m\e[40m"); % bold,white/black
  set_color_esc ("keyword3", "\e[0m\e[37m\e[40m");      % lightgray(italic)/black
  set_color_esc ("keyword4", "\e[0m\e[5m\e[37m\e[40m"); % bold,lightgray(italic)/black

  % fixme: underlining does not work
  % set_color_esc ("keyword5", "\e[0m\e[4m\e[77m\e[40m"); % underline,white/black 
  
} else { % fixme: keyword[1-4] should be defined in color-schemes, but aren't ...
  set_color ("keyword1", "green", "black");
  set_color ("keyword2", "yellow", "black");
  set_color ("keyword3", "lightgray", "black");
  set_color ("keyword4", "brown", "black");
  set_color ("keyword5", "magenta", "black");

  % fixme: "operator" definitely is a color-scheme thing, but then ...
  set_color ("operator", "green", "black");
}

%%% DFA_CACHE_BEGIN %%%
static define setup_dfa_callback (name)
{
%  dfa_enable_highlight_cache ("/home/rogalsky/jed/lout.dfa", name); % fixme: delete this line
  dfa_enable_highlight_cache ("lout.dfa", name);

  dfa_define_highlight_rule ("@Use","preprocess", name);
  dfa_define_highlight_rule ("@Open","preprocess", name);
  dfa_define_highlight_rule ("@SysDatabase","preprocess", name);
  dfa_define_highlight_rule ("@Database","preprocess", name);
  dfa_define_highlight_rule ("@IncludeGraphic","preprocess", name);
  dfa_define_highlight_rule ("@SysInclude[ \t]*{[^{}]*}","preprocess", name);
  dfa_define_highlight_rule ("@Include[ \t]*{[^{}]*}","preprocess", name);

  dfa_define_highlight_rule ("#.*$", "comment", name);
  dfa_define_highlight_rule ("@[A-Za-z??-????-????-??]+", "keyword", name);
  dfa_define_highlight_rule ("\\^?(\\||\\|\\||/|//|&)([0-9]+\\.)?[0-9]*[a-z]*", "operator", name);
  dfa_define_highlight_rule ("\"([^\\\\\"]|\\\\.)*\"", "string", name);
  dfa_define_highlight_rule (".", "normal", name);

  dfa_define_highlight_rule ("@B([ \t]+[\\\"A-Za-z??-????-????-??]+|[ \t]*{([^{}]|{([^{}]|{[^{}]*})*})*})","keyword2", name);
  dfa_define_highlight_rule ("@Title([ \t]+[\\\"A-Za-z??-????-????-??]+|[ \t]*{([^{}]|{([^{}]|{[^{}]*})*})*})","keyword2", name);
  dfa_define_highlight_rule ("@I([ \t]+[\\\"A-Za-z??-????-????-??]+|[ \t]*{([^{}]|{([^{}]|{[^{}]*})*})*})","keyword3", name);
  dfa_define_highlight_rule ("@BI([ \t]+[\\\"A-Za-z??-????-????-??]+|[ \t]*{([^{}]|{([^{}]|{[^{}]*})*})*})","keyword4", name);
  dfa_define_highlight_rule ("@Underline([ \t]+[\\\"A-Za-z??-????-????-??]+|[ \t]*{([^{}]|{([^{}]|{[^{}]*})*})*})","keyword5", name);

  dfa_build_highlight_table (name);
}
dfa_set_init_callback (&setup_dfa_callback, "lout");
%%% DFA_CACHE_END %%%
#endif

%!%+
%\function{lout_is_comment}
%\synopsis{Tests if the current line ends with a comment}
%\usage{Intger_Type lout_is_comment ()}
%\description
% Returns a non zero value, if the current line ends with a comment, else
% tero is returned.
%\seealso{LOUT_IGNORE_COMMENT, lout_mode}
%!%-
define lout_is_comment ()
{
   bol ();
   while (ffind ("\\#")) go_right (2);
   ffind_char ('#'); % return value on stack
}

%!%+
%\function{lout_paragraph_separator}
%\synopsis{Tests if the current line separates two paragraphs}
%\usage{Intger_Type lout_paragraph_separator ()}
%\description
% Returns a non zero value if the current line separates two paragraphs,
% else zero is returned.
%\seealso{LOUT_IGNORE_COMMENT, lout_mode}
%!%-
define lout_paragraph_separator ()
{
   bol_skip_white ();

   if (eolp ()) 
     return 1;

   if (looking_at ("@"))
     {
	if (orelse   % fixme: this are only the most used symbols
	    {looking_at ("@End")}
	    {looking_at ("@Begin")}
	    {looking_at ("@PP")}
	    {looking_at ("@LP")}
	    {looking_at ("@LLP")}
	    {looking_at ("@DP")}
	    {looking_at ("@NP")}
	    {looking_at ("@EQ")}
	    {looking_at ("@Table")}
	    {looking_at ("@Graph")}
	    {looking_at ("@Diag")}
	    {looking_at ("@Figure")}
	    {looking_at ("@Tbl")}
	    {looking_at ("@Lecture")}
	    {looking_at ("@Overhead")}
	    {looking_at ("@Illustration")}
	    {looking_at ("@Chapter")}
	    {looking_at ("@Introduction")}
	    {looking_at ("@Preface")}
	    {looking_at ("@Book")}
	    {looking_at ("@Report")}
	    {looking_at ("@Document")}
	    {looking_at ("@CNP")}
	    {re_looking_at ("@[a-zA-Z]*Display")}
	    {re_looking_at ("@[a-zA-Z]*List")}
	    {re_looking_at ("@[Sub]*Section")}
	    {re_looking_at ("@[Sub]*Appendix")} )
	  return 1;
     }

   %
   %  look for comment
   %
   return not (LOUT_IGNORE_COMMENT) and lout_is_comment ();
} 


%!%+
%\function{lout_wrap_hook}
%\synopsis{Outcomments the current line if the previous one ends with a comment}
%\usage{lout_wrap_hook ()}
%\description
% Outcomments the current line if the previous one ends with a comment. Indents
% the current line.
%\seealso{LOUT_IGNORE_COMMENT, indent_line, lout_mode}
%!%-
define lout_wrap_hook ()
{
  variable yep;
  push_spot ();
  yep = up_1 () and lout_is_comment ();
  pop_spot ();
  if (yep) {
    push_spot ();
    bol_skip_white ();
    insert ("# ");
    pop_spot ();
  }
  indent_line ();
}

%!%+
%\function{lout_isolate_paragraph}
%\synopsis{Narrows from the start of the current paragraph to the current line}
%\usage{lout_isolate_paragraph ()}
%\description
% Narrows all lines from the start of the current paragraph to the current line,
% inclusive.
%\seealso{lout_mode}
%!%-
define lout_isolate_paragraph ()
{
   variable ic = LOUT_IGNORE_COMMENT;
   LOUT_IGNORE_COMMENT = 1;
   push_spot (); push_mark ();
   backward_paragraph ();
   narrow ();
   LOUT_IGNORE_COMMENT = ic;
}


%!%+
%\function{bskip_non_word}
%\synopsis{Back skips non word characters}
%\usage{bskip_non_word ()}
%\description
% This function moves the current editing point backward past all
% non-word characters until a word character is encountered.
% Characters that make up a word are set by the `define_word' function.
% In contrast to \var{bskip_non_word_chars} \var{bskip_non_word} skips
% over line boundaries.
%\seealso{bskip_non_word_chars, lout_mode}
%!%-
define bskip_non_word () {
  while (bskip_non_word_chars (), bolp ()) {
    !if (left (1))
      break;
  }
}

%!%+
%\function{bskip_non_word}
%\synopsis{Back skips non word characters}
%\usage{bskip_non_word ()}
%\description
% This function moves the current editing point backward past all
% non-word characters until a word character is encountered.
% Characters that make up a word are set by the `define_word' function.
% In contrast to \var{bskip_non_word_chars} \var{bskip_non_word} skips
% over line boundaries.
%\seealso{bskip_non_word_chars, lout_mode}
%!%-
define bskip_non_word () {
  while (bskip_non_word_chars (), bolp ()) {
    !if (left (1))
      break;
  }
}

%!%+
%\function{get_word}
%\synopsis{Returns the word at the current point}
%\usage{String_Type get_word ()}
%\description
% Returns the word at the current point.
%\seealso{bufsubstr, get_word_chars, define_word}
%!%-
define get_word () {
  push_spot ();
  bskip_word_chars ();
  push_mark ();
  skip_word_chars ();
  bufsubstr (); % string on the stack
  pop_mark (0);
  pop_spot ();
}

%!%+
%\function{lout_bfind_open_block}
%\synopsis{Seaches backwards for the beginning of the current block}
%\usage{lout_bfind_open_block ()}
%\description
% This function scans backward looking for the first open brace `{'
% or `@Begin' which has not been closed up to the current point. If
% the point is not in an open block an error is raised.
%\seealso{indent_line, find_matching_delimiter}
%!%-
define lout_bfind_open_block () { % fixme: No checks for proper balancing of 
  variable c=1;                   %        `{}' versus `@Begin @End' are performed.
  do {                            %        The code is slow.
    if (re_bsearch("[@{}]")) {
      !if (parse_to_point ()) {
	if (looking_at ("{") or re_looking_at ("@Begin[ \n\t\r]")) {
	  c--;
	} else if (looking_at ("}") or re_looking_at ("@End[ \n\t\r]")) {
	  c++;
	}
      }
    } else {
      error ("Not in a block");
    }
  } while (c);
}

    
%!%+
%\function{lout_indent_line}
%\synopsis{Indents the current line}
%\usage{lout_indent_line ()}
%\description
% Indents the current line according to `lout' syntax rules. The amount of
% added or removed white space relative to the indentation level of the last
% line can be customized with the variable \var{LOUT_INDENTATION}.
%\seealso{indent_line, LOUT_INDENTATION, lout_bfind_open_block}
%!%-
define lout_indent_line () { % fixme: Options of a `lout' symbol dont get indented.
  push_spot ();
  bol ();
  ERROR_BLOCK {
    _clear_error ();
    pop_spot ();
    push_spot ();
    bol_trim ();
    pop_spot ();
    return ();
  }
  lout_bfind_open_block ();
  bol_skip_white ();
  what_column ();
  pop_spot ();
  push_spot ();
  bol_trim ();
  !if (looking_at ("}") or re_looking_at("@End[ \t\n\r]"))
    () + LOUT_INDENTATION;
  whitespace(()-1);
  pop_spot ();
}



%!%+
%\function{indent_region}
%\synopsis{Indents all lines which are part of the region}
%\usage{indent_region ()}
%\description
% Indents all lines which are part of the region, or the current line if
% no region is defined.
%\seealso{indent_line}
%!%-
define indent_region () {
  !if (markp ()) {
    indent_line ();
    return;
  }
  
  check_region (1);
   
  _for (what_line (), (exchange_point_and_mark (), what_line ()), -1) {
    indent_line ();
    go_down_1;
  }
  pop_spot ();
}


%!%+
%\function{insert_indented}
%\synopsis{Inserts a string and indents all lines of the string}
%\usage{indent_region ()}
%\description
% Inserts a string at the current position and indents all lines of
% the string. The point is moved to the end of the inserted text.
%\seealso{indent_line}
%!%-
define insert_indented (str) {
  variable d;
  d = what_line;
  insert (str);
  push_spot ();
  d = what_line - d;
  go_up (d);
  _for (1, d, 1) {
    pop ();
    indent_line ();
    go_down_1 ();
  }
  indent_line ();
  pop_spot ();
}



%!%+
%\variable{lout_tagged_symbols}
%\synopsis{lout_tagged_symbols}
%\description
% An associative array of `lout' symbols which have a @Tag option.
% The keys are designed to be easy to type or easy to remember.
%\seealso{lout_symbols, lout_symbol, lout_mode}
%!%-
variable lout_tagged_symbols = Assoc_Type [String_Type]; 
% fixme: decide upon which symbols to include and which to exclude
%
%  
lout_tagged_symbols["numbereddisplay"] =                   "@NumberedDisplay";
lout_tagged_symbols["leftnumbereddisplay"] =               "@LeftNumberedDisplay";
%lout_tagged_symbols["centerednumbereddisplay"] =           "@CenteredNumberedDisplay";
lout_tagged_symbols["centrednumbereddisplay"] =            "@CentredNumberedDisplay";
lout_tagged_symbols["rightnumbereddisplay"] =              "@RightNumberedDisplay";
lout_tagged_symbols["quotednumbereddisplay"] =             "@QuotedNumberedDisplay";
lout_tagged_symbols["indentednumbereddisplay"] =           "@IndentedNumberedDisplay";
%
lout_tagged_symbols["rawnumbereddisplay"] =                "@RawNumberedDisplay";
lout_tagged_symbols["rawleftnumbereddisplay"] =            "@RawLeftNumberedDisplay";
%lout_tagged_symbols["rawcenterednumbereddisplay"] =        "@RawCenteredNumberedDisplay";
lout_tagged_symbols["rawcentrednumbereddisplay"] =         "@RawCentredNumberedDisplay";
lout_tagged_symbols["rawrightnumbereddisplay"] =           "@RawRightNumberedDisplay";
lout_tagged_symbols["rawquotednumbereddisplay"] =          "@RawQuotedNumberedDisplay";
lout_tagged_symbols["rawindentednumbereddisplay"] =        "@RawIndentedNumberedDisplay";
%
lout_tagged_symbols["alignednumbereddisplay"] =            "@AlignedNumberedDisplay";
lout_tagged_symbols["leftalignednumbereddisplay"] =        "@LeftAlignedNumberedDisplay";
%lout_tagged_symbols["centerealigneddnumbereddisplay"] =    "@CenteredAlignedNumberedDisplay";
lout_tagged_symbols["centredalignednumbereddisplay"] =     "@CentredAlignedNumberedDisplay";
lout_tagged_symbols["rightalignednumbereddisplay"] =       "@RightAlignedNumberedDisplay";
lout_tagged_symbols["quotedalignednumbereddisplay"] =      "@QuotedAlignedNumberedDisplay";
lout_tagged_symbols["indentedalignednumbereddisplay"] =    "@IndentedAlignedNumberedDisplay";
%
lout_tagged_symbols["rawalignednumbereddisplay"] =         "@RawAlignedNumberedDisplay";
lout_tagged_symbols["rawleftalignednumbereddisplay"] =     "@RawLeftAlignedNumberedDisplay";
%lout_tagged_symbols["rawcenteredalignednumbereddisplay"] = "@RawCenteredAlignedNumberedDisplay";
lout_tagged_symbols["rawcentredalignednumbereddisplay"] =  "@RawCentredAlignedNumberedDisplay";
lout_tagged_symbols["rawrightalignednumbereddisplay"] =    "@RawRightAlignedNumberedDisplay";
lout_tagged_symbols["rawquotedalignednumbereddisplay"] =   "@RawQuotedAlignedNumberedDisplay";
lout_tagged_symbols["rawindentedalignednumbereddisplay"] = "@RawIndentedAlignedNumberedDisplay";

%!%+
%\variable{lout_symbols}
%\synopsis{lout_symbols}
%\description
% An associative array of `lout' symbols.
% The keys are designed to be easy to type or easy to remember.
%\seealso{lout_tagged_symbols, lout_symbol, lout_mode}
%!%-
variable lout_symbols = Assoc_Type [String_Type];
% fixme: decide upon which symbols to include and which to exclude
lout_symbols["eq"] =                        "@Eq";
%
lout_symbols["B"] =                         "@B";
lout_symbols["I"] =                         "@I";
lout_symbols["BI"] =                        "@BI";
lout_symbols["S"] =                         "@S";
lout_symbols["R"] =                         "@R";
lout_symbols["F"] =                         "@F";
lout_symbols["II"] =                        "@II";
lout_symbols["underline"] =                 "@Underline";
%
lout_symbols["tag"] =                       "@Tag";
lout_symbols["listitem"] =                  "@ListItem";
lout_symbols["tagitem"] =                   "@TagItem";
%
lout_symbols["pageof"] =                    "@PageOf";
lout_symbols["pagemark"] =                  "@PageMark";
lout_symbols["numberof"] =                  "@NumberOf";
%
lout_symbols["footnote"] =                  "@FootNote";
lout_symbols["leftnote"] =                  "@LeftNote";
lout_symbols["rightnote"] =                 "@RightnNote";
lout_symbols["innernote"] =                 "@InnerNote";
lout_symbols["outernote"] =                 "@OuterNote";
%
lout_symbols["box"] =                       "@Box";
lout_symbols["curvebox"] =                  "@CurveBox";
lout_symbols["shadowbox"] =                 "@ShadowBox";
lout_symbols["include"] =                   "@Include";
lout_symbols["sysinclude"] =                "@SysInclude";
lout_symbols["includegraphic"] =            "@IncludeGraphic";
%
lout_symbols["graph"] =                     "@Graph";
lout_symbols["data"] =                      "@Data";
lout_symbols["diag"] =                      "@Diag";
%
lout_symbols["heading"] =                   "@Heading";
lout_symbols["display"] =                   "@Display";
lout_symbols["leftdisplay"] =               "@LeftDisplay";
%lout_symbols["centereddisplay"] =           "@CenteredDisplay";
lout_symbols["centreddisplay"] =            "@CentredDisplay";
lout_symbols["rightdisplay"] =              "@RightDisplay";
lout_symbols["quoteddisplay"] =             "@QuotedDisplay";
lout_symbols["indenteddisplay"] =           "@IndentedDisplay";
%
lout_symbols["rawdisplay"] =                "@RawDisplay";
lout_symbols["rawleftdisplay"] =            "@RawLeftDisplay";
%lout_symbols["rawcentereddisplay"] =        "@RawCenteredDisplay";
lout_symbols["rawcentreddisplay"] =         "@RawCentredDisplay";
lout_symbols["rawrightdisplay"] =           "@RawRightDisplay";
lout_symbols["rawquoteddisplay"] =          "@RawQuotedDisplay";
lout_symbols["rawindenteddisplay"] =        "@RawIndentedDisplay";
%
lout_symbols["aligneddisplay"] =            "@AlignedDisplay";
lout_symbols["leftaligneddisplay"] =        "@LeftAlignedDisplay";
%lout_symbols["centerealignedddisplay"] =    "@CenteredAlignedDisplay";
lout_symbols["centredaligneddisplay"] =     "@CentredAlignedDisplay";
lout_symbols["rightaligneddisplay"] =       "@RightAlignedDisplay";
lout_symbols["quotedaligneddisplay"] =      "@QuotedAlignedDisplay";
lout_symbols["indentedaligneddisplay"] =    "@IndentedAlignedDisplay";
%
lout_symbols["rawaligneddisplay"] =         "@RawAlignedDisplay";
lout_symbols["rawleftaligneddisplay"] =     "@RawLeftAlignedDisplay";
%lout_symbols["rawcenteredaligneddisplay"] = "@RawCenteredAlignedDisplay";
lout_symbols["rawcentredaligneddisplay"] =  "@RawCentredAlignedDisplay";
lout_symbols["rawrightaligneddisplay"] =    "@RawRightAlignedDisplay";
lout_symbols["rawquotedaligneddisplay"] =   "@RawQuotedAlignedDisplay";
lout_symbols["rawindentedaligneddisplay"] = "@RawIndentedAlignedDisplay";


%!%+
%\variable{lout_keywords}
%\synopsis{lout_keywords}
%\description
% An associative array of `lout' keywords.
% The keys are designed to be easy to type or easy to remember.
%\seealso{lout_mode}
%!%-
variable lout_keywords = Assoc_Type [String_Type];
% fixme: decide upon which symbols to include and which to exclude
lout_keywords["end"] = "@End";
lout_keywords["endlist"] = "@EndList";
lout_keywords["endsection"] = "@EndSection";
lout_keywords["endsubsection"] = "@EndSubSection";
lout_keywords["endsubsubsection"] = "@EndSubSubSection";
lout_keywords["endappendix"] = "@EndAppendix";
lout_keywords["endsubappendix"] = "@EndSubAppendix";
lout_keywords["endsubsubappendix"] = "@EndSubSubAppendix";
lout_keywords["endsections"] = "@EndSections";
lout_keywords["endsubsections"] = "@EndSubSections";
lout_keywords["endsubsubsections"] = "@EndSubSubSections";
lout_keywords["endappendices"] = "@EndAppendices";
lout_keywords["endsubappendices"] = "@EndSubAppendices";
lout_keywords["endsubsubappendices"] = "@EndSubSubAppendices";
lout_keywords["text"] = "@Text";


   
%!%+
%\variable{lout_fonts}
%\synopsis{lout_fonts}
%\description
% An associative array of `lout' font names.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_symbol, lout_mode}
%!%-
variable lout_fonts = Assoc_Type [String_Type];
% fixme: more fonts?
lout_fonts["avantgarde"] = "AvantGarde";
lout_fonts["bookman"] = "Bookman";
lout_fonts["chancey"] = "Chancey";
lout_fonts["courier"] = "Courier";
lout_fonts["helvetica"] = "Helvetica";
lout_fonts["schoolbook"] = "Schoolbook";
lout_fonts["palatino"] = "Palatino";
lout_fonts["symbol"] = "Symbol";
lout_fonts["times"] = "Times";
lout_fonts["dingbats"] = "Dingbats";

%!%+
%\variable{lout_faces}
%\synopsis{lout_faces}
%\description
% An associative array of `lout' font face names.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_fonts, lout_mode}
%!%-
variable lout_font_faces= Assoc_Type [String_Type];
lout_font_faces["base"] = "Base";
lout_font_faces["slope"] = "Slope";
lout_font_faces["bold"] = "Bold";
lout_font_faces["boldslope"] = "BoldSlope";

%!%+
%\variable{lout_floats}
%\synopsis{lout_floats}
%\description
% An associative array of `lout' floating structures.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_floats, lout_mode}
%!%-
variable lout_floats = Assoc_Type [String_Type];
% fixme: decide upon which symbols to include and which to exclude
lout_floats["figure"] = "@Figure";
lout_floats["table"] = "@Table";


%!%+
%\variable{lout_lists}
%\synopsis{lout_lists}
%\description
% An associative array of `lout' list symbols.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_list, lout_insert, lout_mode}
%!%-
variable lout_lists = Assoc_Type [String_Type];
% fixme: decide upon which symbols to include and which to exclude
lout_lists["list"] = "@List";
lout_lists["leftlist"] = "@LeftList";
lout_lists["indentedlist"] = "@IndentedList";
lout_lists["quotedlist"] = "@QuotedList";
%lout_lists["centeredlist"] = "@CenteredList";
lout_lists["centredlist"] = "@CentredList";
lout_lists["numberedlist"] = "@NumberedList";
lout_lists["romanlist"] = "@RomanList";
lout_lists["ucromanlist"] = "@UCRomanList";
lout_lists["alphalist"] = "@AlphaList";
lout_lists["ucalphalist"] = "@UCAlphaList";
lout_lists["parennumberedlist"] = "@ParenNumberedList";
lout_lists["parenromanlist"] = "@ParenRomanList";
lout_lists["parenucromanlist"] = "@ParenUCRomanList";
lout_lists["parenalphalist"] = "@ParenAlphaList";
lout_lists["parenucalphalist"] = "@ParenUCAlphaList";
lout_lists["bulletlist"] = "@BulletList";
lout_lists["starlist"] = "@StarList";
lout_lists["dashlist"] = "@DashList";

%!%+
%\variable{lout_tagged_lists}
%\synopsis{lout_tagged_lists}
%\description
% An associative array of `lout' tagged list symbols.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_list, lout_insert, lout_mode}
%!%-
variable lout_tagged_lists = Assoc_Type [String_Type];
lout_tagged_lists["taggedlist"] = "@TaggedList";
lout_tagged_lists["widetaggedlist"] = "@WideTaggedList";
lout_tagged_lists["verywidetaggedlist"] = "@VeryWideTaggedList";


%!%+
%\variable{lout_large_scales}
%\synopsis{lout_large_scales}
%\description
% An associative array of `lout' large scale symbols.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_large_scale, lout_insert, lout_mode}
%!%-
variable lout_large_scales = Assoc_Type [String_Type];
lout_large_scales["beginsections"] =         "@BeginSections";
lout_large_scales["beginsubsections"] =      "@BeginSubSections";
lout_large_scales["beginsubsubsections"] =   "@BeginSubSubSections";
lout_large_scales["beginappendices"] =       "@BeginAppendices";
lout_large_scales["beginsubappendices"] =    "@BeginSubAppendices";
lout_large_scales["beginsubsubappendices"] = "@BeginSubSubAppendices";

%!%+
%\variable{lout_sections}
%\synopsis{lout_sections}
%\description
% An associative array of `lout' section symbols.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_large_scale, lout_insert_section, lout_insert, lout_mode}
%!%-
variable lout_sections = Assoc_Type [String_Type];
lout_sections["chapter"] =        "@Chapter";
lout_sections["section"] =        "@Section";
lout_sections["subsection"] =     "@SubSection";
lout_sections["subsubsection"] =  "@SubSubSection";
lout_sections["appendix"] =       "@Appendix";
lout_sections["subappendix"] =    "@SubAppendix";
lout_sections["subsubappendix"] = "@SubSubAppendix";
lout_sections["overhead"] =       "@Overhead";

%\variable{lout_document_styles}
%\synopsis{lout_document_styles}
%\description
% An associative array of `lout' document style symbols.
% The keys are desiged to be easy to type or easy to remember.
%\seealso{lout_insert_document, LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
variable lout_document_styles = Assoc_Type [String_Type];
lout_document_styles["document"] =     "@Document";
lout_document_styles["report"] =       "@Report";
lout_document_styles["book"] =         "@Book";
lout_document_styles["slides"] =       "@OverheadTransparencies";
lout_document_styles["illustration"] = "@Illustration";

% lout_markups += "tbl,break"


	   
%!%+
%\variable{lout_key_completions}
%\synopsis{lout_key_completions}
% A komma separated list of lout symbol keys used in the auto completer of
% \var{lout_insert_symbol}.
%\seealso{lout_completions, lout_symbol, lout_mode}
%!%-
variable lout_key_completions = "font,";
lout_key_completions += strjoin (assoc_get_keys (lout_symbols),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_tagged_symbols),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_floats),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_lists),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_tagged_lists),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_large_scales),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_sections),",") + ",";
lout_key_completions += strjoin (assoc_get_keys (lout_keywords),",");

%!%+
%\variable{lout_last_symbol}
%\synopsis{lout_last_symbol}
% The \var{lout_last_keys} variable remebers the last used symbol in 
% \var{lout_symbol} and is used therein as default.
%\seealso{lout_symbol, lout_mode}
%!%-
variable lout_last_symbol = "";

%!%+
%\function{strcommon}
%\synopsis{Finds the longest common substring in an array of strings}
%\usage{String_Type strcommon (Array_Type [String_Type])}
%\description
% Finds the longest common substring in an array of strings. E.g.
% strcommon(["foot", "foobar", "fool"]) yields "foo".
%\seealso{substr}
%!%-
define strcommon (strs) {
  variable e = 1, len = 0, size = length (strs)-1, c, i;
  
  do {
    len++;
    c = substr(strs[0], len, 1);
    _for (1, size, 1) {
      i = ();
      if (c != substr(strs[i], len, 1)) {
	e = 0;
	break;
      }
    }
  } while (e);
  
  substr(strs[0], 1, len-1);
}


%!%+
%\function{lout_complete_text}
%\synopsis{Completes a `lout' symbol at the current position}
%\usage{lout_complete_text ()}
%\description
% The \var{lout_complete_text} function completes a `lout' symbol at the
% current position. If no completion can be found an error will be raised.
%\seealso{lout_complete_or_indent, lout_completions, lout_mode}
%!%-
define lout_complete_text () {
  variable matches = 0; % number of beginnings of keywords that match the last word
  variable keywords = ""; % list of keywords
  variable word, tmp;
  
  bskip_word_chars ();
  push_mark ();
  skip_word_chars ();
  word = bufsubstr ();
  pop_mark (0);

  if (word=="")
    error ("There is nothing to complete.");

  
  if (is_substr ("@Font", word) == 1) {
    matches = 1;
    keywords = "@Font,";
  }
  foreach ([lout_symbols, lout_tagged_symbols, lout_floats, lout_lists,
	    lout_tagged_lists,lout_large_scales,lout_sections,lout_keywords]) {
    foreach () using ("values") {
      tmp = ();
      if (is_substr (tmp, word) == 1) {
	matches++;
	keywords += tmp + ",";
      }
    }
  }

  
  !if (matches)
    error ("No Completion found.");

  % strip off the last ","
  keywords = keywords[[0:-2]];

  % there is only one match, insert it and return
  if (matches == 1) {
    insert (keywords[[strlen(word):]]+" ");
    lout_last_symbol = keywords;
    return;
  }

  % complete as far as and if possible, then return
  tmp = strcommon(strchop(keywords,',',0));
  if (tmp != word) {
    insert (tmp[[strlen (word):]]);
    lout_last_symbol = keywords;
    return;
  }

  % ask for the completion
  ERROR_BLOCK {
    _clear_error ();
  }
  lout_last_symbol = "";
  lout_last_symbol = read_with_completion (keywords, "Keyword:", lout_last_symbol, word, 's');
  insert (lout_last_symbol[[strlen(word):]]+" ");
}


%!%+
%\variable{lout_tag_counters}
%\synopsis{lout_tag_counters}
%\description
% The associative array \var{lout_tag_counters} remebers the number the next
% to be used tag. Each `lout' symbol has its own key in \var{lout_tag_counters},
% where the key is constructed from the capital letters of the symbol. The default
% tag which is used in \var{lout_symbol} is build up from the key and the
% number associted with that key.
%\seealso{lout_symbol, lout_short_symbol, lout_mode}
%!%-
variable lout_tag_counters = Assoc_Type [Integer_Type];


%!%+
%\function{lout_short_symbol}
%\synopsis{Creates an abbrevation of a `lout' symbol}
%\usage{String_Type lout_short_symbol (String_Type longsymbol)}
%\description
% Returns an abbrevation of the symbol \var{longsymbol} consisting of the capital
% letters therein. The '@' character is considered to be lower case.
%\seealso{lout_tag_counters, lout_symbol, lout_mode}
%!%-
define lout_short_symbol (LongSymbol) {
  variable shortSymbol = "";
  variable c;
  
  if (LongSymbol[0] == '@')  % skip '@'
    LongSymbol = LongSymbol[[1:]];
  
  foreach (LongSymbol) {
    c = ();
    if ( c == toupper (c) )
      shortSymbol += char (c);
  }
  return shortSymbol;
}


%!%+
%\function{lout_insert_tag}
%\synopsis{Asks the user for a tag to insert}
%\usage{lout_insert_tag (String_Type shortsymbol)}
%\description
% Asks the user for a tag to insert and presents him a default based on
% \var{shortsymbol}.
%\seealso{lout_tag_counters, lout_short_symbol, lout_symbol, 
% lout_insert_caption, lout_mode}
%!%-
define lout_insert_tag (sm) {
  variable dtag, tag = "";

  !if (assoc_key_exists (lout_tag_counters,sm))
    lout_tag_counters[sm] = 1;
  dtag = sm + string (lout_tag_counters[sm]);
  
  ERROR_BLOCK {
    tag = "";
    _clear_error ();
  }
  tag = read_mini ("Enter tag:", dtag, "");
  
  
  if (tag != "") {
    if (is_substr (tag,sm) == 1) {
      $1 = tag[[strlen(sm):]];
      if (_slang_guess_type ($1) == Integer_Type)
	lout_tag_counters[sm]=integer($1)+1;
    }
    insert_indented ("\n at Tag { ");
    insert (tag);
    insert_indented (" }");
  } 
}

%!%+
%\function{lout_insert_caption}
%\synopsis{Asks the user for a caption to insert}
%\usage{lout_insert_caption ()}
%\description
% Asks the user for a caption to insert.
%\seealso{lout_tag_counters, lout_short_symbol, lout_symbol,
% lout_insert_tag, lout_mode}
%!%-
define lout_insert_caption () {
  variable cap;

  cap = read_mini ("Enter caption:", "", "");
  insert_indented ("\n at Caption { ");
  insert (cap);
  insert_indented (" }");
}



%!%+
%\function{lout_insert_symbol}
%\synopsis{Inserts a `lout' symbol}
%\usage{lout_insert_symbol (String_Type symbol)}
%\description
% Inserts a \var{symbol} template at the current point.
%\seealso{lout_insert_tagged_symbol, lout_mode}
%!%-
define lout_insert_symbol (Symbol) {
  insert (Symbol);
  insert (" { ");
  if (markp) 
    pop_mark (1);
  insert (" }");
  () = left (2);
}

%!%+
%\function{lout_insert_tagged_symbol}
%\synopsis{Inserts a `lout' symbol with a tag}
%\usage{lout_insert_tagged_symbol (String_Type Symbol, Integer_Type nonewlines)}
%\description
% Inserts a \var{symbol} template with a tag option at the current point.
% If \var{nonewlines} is non zero the no newlines will be inserted.
%\seealso{lout_insert_symbol, lout_mode}
%!%-
define lout_insert_tagged_symbol (Symbol, nonewlines) {
  insert_indented (Symbol);
  lout_insert_tag (lout_short_symbol (Symbol));

  if (nonewlines) {
    insert (" { ");
  } else {
    insert_indented ("\n{\n");
  }
  
  if (markp)
    pop_mark (1);

  if (nonewlines) {
    insert (" }");
    () = left (2);
  } else {
    insert_indented ("\n}\n");
    go_up (2); 
    eol ();
  }
}


%!%+
%\function{lout_insert_float}
%\synopsis{Inserts a `lout' template for a float}
%\usage{lout_insert_float (String_Type Symbol)}
%\description
% Inserts a \var{Symbol} template with a tag and caption option at the current point.
%\seealso{lout_insert, lout_insert_tag, lout_insert_caption, lout_mode}
%!%-
define lout_insert_float (Symbol) {
  insert_indented (Symbol);
  lout_insert_tag (lout_short_symbol (Symbol));
  lout_insert_caption ();

  insert_indented ("\n at Begin\n");
  if (markp)
    pop_mark (1);
  insert ("\n at End ");
  insert (Symbol);
  insert_indented ("\n");
  go_up (2); 
  eol ();
}

%!%+
%\function{lout_insert_list}
%\synopsis{Inserts a `lout' template for a list}
%\usage{lout_insert_list (String_Type Symbol)}
%\description
% Inserts a \var{Symbol} template for a list at the current point.
%\seealso{lout_insert, lout_insert_tagged_list, lout_mode}
%!%-
define lout_insert_list (Symbol) {
  insert_indented (Symbol);
  insert_indented ("\n at ListItem { ");
  if (markp)
    pop_mark (1);
  insert_indented (" }\n at EndList\n");
  go_up (2); 
  eol ();
  () = left (2);
}

%!%+
%\function{lout_insert_taggedlist}
%\synopsis{Inserts a `lout' template for a tagged list}
%\usage{lout_insert_tagged_list (String_Type Symbol)}
%\description
% Inserts a \var{Symbol} template for a tagged list at the current point.
%\seealso{lout_insert, lout_insert_list, lout_mode}
%!%-
define lout_insert_tagged_list (Symbol) {
  insert_indented (Symbol);
  insert_indented ("\n at TagItem { ");
  read_mini ("Enter tag:", "", "");
  insert (());
  insert (" } { ");
  if (markp)
    pop_mark (1);
  insert_indented (" }\n at EndList\n");
  go_up (2); 
  eol ();
  () = left (2);
}


%!%+
%\function{lout_insert_font}
%\synopsis{Inserts a `lout' font}
%\usage{lout_insert_symbol ()}
%\description
% Inserts a `lout' font template at the current point and asks for the family,
% face and size of the font.
%\seealso{lout_insert, LOUT_DEFAULT_FONT, LOUT_DEFAULT_FONT_FACE, lout_mode}
%!%-
define lout_insert_font () {
  variable tmp;
  
  insert ("{ ");
  tmp = strjoin (assoc_get_keys (lout_fonts),",");
  tmp = read_with_completion (tmp, "Enter fontname:", LOUT_DEFAULT_FONT, "", 's');
  insert (lout_fonts[tmp]);
  insert(" ");
  ERROR_BLOCK {
    _clear_error ();
    ""; 
  }
  tmp = strjoin (assoc_get_keys (lout_font_faces),",");
  tmp = read_with_completion (tmp, "Enter face:", LOUT_DEFAULT_FONT_FACE, "", 's');
  insert (lout_font_faces[tmp]);
  if (tmp != "")
    insert(" ");
  tmp = read_mini ("Enter size:", LOUT_DEFAULT_FONT_SIZE, "");
  insert (tmp);
  if (tmp != "")
    insert(" "); 
  insert ("} @Font { ");
  if (markp)
    pop_mark (1);
  insert (" }");
  () = left (2); 
}

%!%+
%\function{lout_insert_section}
%\synopsis{Inserts a `lout' template for a section structure}
%\usage{lout_insert_section (String_Type Symbol)}
%\description
% Inserts a \var{Symbol} template with a tag and title option at the current point.
%\seealso{lout_insert, lout_insert_large_scale, lout_mode}
%!%-
define lout_insert_section (Symbol) {
  insert (Symbol);
  lout_insert_tag (lout_short_symbol (Symbol));
  insert_indented ("\n at Title { ");
  create_user_mark ();
  insert_indented (" }\n at Begin\n at LP\n");
  if (markp)
    pop_mark (1);
  insert_indented ("\n at End ");
  insert (Symbol);
  insert_indented ("\n");
  goto_user_mark ();
%  go_up (2); 
%  eol ();
%  () = left (2);
}


%!%+
%\function{lout_insert_large_scale}
%\synopsis{Inserts a `lout' template for a large scale structure}
%\usage{lout_insert_large_scale (String_Type Symbol)}
%\description
% Inserts a \var{Symbol} template with a tag and title option at the current point.
%\seealso{lout_insert, lout_insert_section, lout_mode}
%!%-
define lout_insert_large_scale (Symbol) {
  insert (Symbol);
  insert_indented ("\n");
  if (markp)
    pop_mark (1);
  insert ("\n at End");
  insert (Symbol[[6:]]);
  indent_line (); newline (); 
  go_up (2); 
  eol ();
}



%!%+
%\function{lout_what_ls}
%\synopsis{Returns the current large scale environment}
%\usage{String_Type lout_what_ls ()}
%\description
% If the point is in a `lout' large scale environment, defined by 
% @Begin(Sub)*(Sections|Appendices) ... @End(Sub)*(Sections|Appendices),
% this function returns @Begin(Sub)*(Sections|Appendices), else the null
% string is returned.
%\seealso{lout_what_sec, lout_insert_section, lout_insert_large_scale, lout_mode}
%!%-
define lout_what_ls () {
  variable ls, depth = 1;
  push_spot ();
  
  do {
    if (re_bsearch ("@[BE][en][gd]i?n?S?u?b?S?u?b?[SA][ep][cp][te][in][od][ni][sc]e?s?")) {
      ls = regexp_nth_match (0);
      if (ls[[:3]]=="@End")
	depth++;
      else
	depth--;
    } else {
      ls="";
      break;
    }
  } while (depth);
  pop_spot ();
  ls;
}  


%!%+
%\Function{lout_what_sec}
%\synopsis{Returns the current section environment}
%\usage{String_Type lout_what_sec ()}
%\description
% If the point is in a `lout' section environment, defined by 
% @(Sub)*(Section|Appendix) ... @End @(Sub)*(Section|Appendix),
% this function returns @(Sub)*(Section|Appendix), else the null
% string is returned.
%\seealso{lout_what_ls, lout_insert_section, lout_insert_large_scale, lout_mode}
%!%-
define lout_what_sec () {
  variable ls, depth = 1;
  push_spot ();
  
  do {
    if (re_bsearch ("@S?u?b?S?u?b?[SA][ep][cp][te][in][od][ni]x?")) {
      push_spot ();
      ls = regexp_nth_match (0);
      bskip_non_word ();
      push_mark ();
      bskip_word ();
      if (bufsubstr ()=="@End") % bufsubstr pops the mark!
	depth++;
      else
	depth--;
      pop_spot ();
    } else {
      ls="";
      break;
    }
  } while (depth);

  pop_spot ();
  ls;
}  


%!%+
%\function{lout_smart_insert_section}
%\synopsis{Asks the user for a `lout' section to insert}
%\usage{lout_smart_insert_section ()}
%\description
% Asks the user for a section symbol and its standard options to be inserted at
% the current point. A reasonable default will be given. An eventually defined 
% region will be enclosed in the symbols body.
%\seealso{lout_insert lout_key_completions, lout_mode}
%!%-
define lout_smart_insert_section () {
  variable ls, sec, mark, point, regionp = 0;
  
  if (markp ()) {
    check_region (0);
    mark = create_user_mark();
    exchange_point_and_mark ();
    point = create_user_mark();
    regionp = 1;
  }

  sec = lout_what_sec ();
  ls = lout_what_ls ();

  if (regionp) { % sec destroys the region :-(
    goto_user_mark (mark);
    push_mark ();
    goto_user_mark (point);
  }
  
  if (sec=="") {
    if (ls=="") {
      ls = read_with_completion("@BeginSections, at BeginAppendices",
				"Enter large scale structure:",
				"@BeginSections",
				"",
				's');
      lout_insert_large_scale (ls);
      if (regionp) { % restore the original region
	goto_user_mark (mark);
	push_mark ();
	goto_user_mark (point);
	() = right (strlen(ls)+1);
      }
    } 
  } else { % sec!=""
    switch (sec[[-7:]])
    { case "Section" :
      ls = "@BeginSub"+sec[[1:]]+"s"; }
    { case "ppendix" :
      ls = "@BeginSub"+sec[[1:-2]]+"ces"; }

    lout_insert_large_scale (ls);
    if (regionp) { % restore the original region
      goto_user_mark (mark);
      push_mark ();
      goto_user_mark (point);
      () = right (strlen(ls)+1);
    }
  }
  

  switch (ls[[-8:]])
  { case "Sections" :
    lout_insert_section ("@"+ls[[6:-2]]); } 
  { case "pendices" :
    lout_insert_section ("@"+ls[[6:-4]]+"x"); }
}

%!%+
%\function{lout_insert}
%\synopsis{Asks the user for a `lout' symbol to insert}
%\usage{lout_insert ()}
%\description
% Asks the user for a symbol and its standard options to be inserted at
% the current point. An eventually defined region will be enclosed in the
% symbols body.
%\seealso{lout_insert_symbol,lout_insert_tagged_symbol, lout_insert_font,
% lout_insert_floats, lout_insert_section, lout_insert_list, lout_key_completions,
% lout_mode}
%!%-
define lout_insert () {
  variable tmp;
  
  if (markp ()) {
    check_region (0);
    exchange_point_and_mark ();
  }
  
  if (lout_last_symbol[0] == '@')
    lout_last_symbol = strlow (lout_last_symbol[[1:]]);
  

  lout_last_symbol = read_with_completion 
    (lout_key_completions, "Enter symbol:", lout_last_symbol, "", 's');
  
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  switch (lout_last_symbol)
  { lout_last_symbol == "font" :
    lout_insert_font ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { assoc_key_exists (lout_symbols, lout_last_symbol) : % these Symbols don't have a @Tag option!
    lout_insert_symbol (lout_symbols[lout_last_symbol]);
  } 
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { assoc_key_exists (lout_tagged_symbols, lout_last_symbol) :
    lout_insert_tagged_symbol (lout_tagged_symbols[lout_last_symbol], 0);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { assoc_key_exists (lout_floats, lout_last_symbol) :
    lout_insert_float (lout_floats[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { assoc_key_exists (lout_lists, lout_last_symbol) :
    lout_insert_list (lout_lists[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { assoc_key_exists (lout_tagged_lists, lout_last_symbol) :
    lout_insert_tagged_list (lout_tagged_lists[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { assoc_key_exists (lout_large_scales, lout_last_symbol) :
    lout_insert_large_scale (lout_large_scales[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { assoc_key_exists (lout_sections, lout_last_symbol) :
    lout_insert_section (lout_sections[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { assoc_key_exists (lout_keywords, lout_last_symbol) :
    insert (lout_keywords[lout_last_symbol]);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  { % else of switch
    lout_insert_tagged_symbol (lout_last_symbol, 1);
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}

%!%+
%\function{lout_insert_document}
%\synopsis{Inserts the template for a new document}
%\usage{lout_insert_document ()}
%\description
% Inserts the template for a new document.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_insert_document () {
  insert ("@SysInclude { doc }\n");
  insert ("@Document\n");
  insert ("@InitialFont { "
		+lout_fonts[LOUT_DEFAULT_FONT]+" "
		+lout_font_faces[LOUT_DEFAULT_FONT_FACE]+" "
		+LOUT_DEFAULT_FONT_SIZE+" }\n");
  insert ("#@InitialBreak { adjust 1.2fx hyphen }\n");
  insert ("#@InitialSpace { lout }\n");
  insert ("#@InitialLanguage { English }\n");
  insert ("#@PageOrientation { Portrait }\n");
  insert ("#@PageHeaders { Simple }\n");
  insert ("#@FirstPageNumber { 1 }\n");
  insert ("#@ColumnNumber { 1 }\n");
  insert ("#@OptimizePages { No }\n");
  insert ("#@Unpaginated { No }\n");
  insert ("//\n");
  insert ("@Text @Begin\n");
  whitespace(LOUT_INDENTATION);
  insert ("\n at End @Text\n");
  go_up (2);
  eol ();
}

%!%+
%\function{lout_insert_report}
%\synopsis{Inserts the template for a new report}
%\usage{lout_insert_report ()}
%\description
% Inserts the template for a new report.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_insert_report () {
  insert ("@SysInclude { report }\n");
  insert ("@Report\n");
  insert ("@Title {  }\n");
  insert ("@Author {  }\n");
  insert ("@Institution {  }\n");
  insert ("@DateLine { Yes }\n");
  insert ("#@AtEnd {  }\n");
  insert ("@CoverSheet { Yes }\n");
  insert ("@ContentsSeparate { No }\n");
  insert ("@AbstractDisplay { Yes }\n");
  insert ("#@AbstractTitle { Abstract }\n");
  insert ("@InitialFont { "
		+lout_fonts[LOUT_DEFAULT_FONT]+" "
		+lout_font_faces[LOUT_DEFAULT_FONT_FACE]+" "
		+LOUT_DEFAULT_FONT_SIZE+" }\n");
  insert ("#@InitialBreak { adjust 1.2fx hyphen }\n");
  insert ("#@InitialSpace { lout }\n");
  insert ("#@InitialLanguage { English }\n");
  insert ("#@PageOrientation { Portrait }\n");
  insert ("#@PageHeaders { Simple }\n");
  insert ("#@FirstPageNumber { 1 }\n");
  insert ("#@ColumnNumber { 1 }\n");
  insert ("#@OptimizePages { No }\n");
  insert ("#@Unpaginated { No }\n");
  insert ("@Abstract {  }\n");
  insert ("//\n");
}

%!%+
%\function{lout_insert_book}
%\synopsis{Inserts the template for a new book}
%\usage{lout_insert_book ()}
%\description
% Inserts the template for a new book.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_insert_book () {
  insert ("@SysInclude { book }\n");
  insert ("@Book\n");
  insert ("@Title {  }\n");
  insert ("@Author {  }\n");
  insert ("@Edition {  }\n");
  insert ("@Publisher {  }\n");
  insert ("@BeforeTitlePage {  }\n");
  insert ("@OnTitlePage {  }\n");
  insert ("@AfterTitlePage {  }\n");
  insert ("@AtEnd {  }\n");
  insert ("@CoverSheet { Yes }\n");
  insert ("@ContentsSeparate { No }\n");
  insert ("@AbstractDisplay { Yes }\n");
  insert ("#@AbstractTitle { Abstract }\n");
  insert ("@InitialFont { "
		+lout_fonts[LOUT_DEFAULT_FONT]+" "
		+lout_font_faces[LOUT_DEFAULT_FONT_FACE]+" "
		+LOUT_DEFAULT_FONT_SIZE+" }\n");
  insert ("#@InitialBreak { adjust 1.2fx hyphen }\n");
  insert ("#@InitialSpace { lout }\n");
  insert ("#@InitialLanguage { English }\n");
  insert ("#@PageOrientation { Portrait }\n");
  insert ("#@PageHeaders { Titles }\n");
  insert ("#@FirstPageNumber { 1 }\n");
  insert ("#@IntroFirstPageNumber { 1 }\n");
  insert ("#@ColumnNumber { 1 }\n");
  insert ("#@OptimizePages { No }\n");
  insert ("//\n");

  insert ("#@Preface\n");
  insert ("#@Title {  }\n");
  insert ("#@Begin\n");
  insert ("#@End @Preface\n\n");
  
  insert ("@Introduction\n");
  insert ("@Begin\n");
  insert ("@End @Introduction\n\n");
  
  insert ("@Chapter\n");
  insert ("@Title {  }\n");
  insert ("@Begin\n");
  insert ("@End @Chapter\n\n");
}

%!%+
%\function{lout_insert_slides}
%\synopsis{Inserts the template for new slides}
%\usage{lout_insert_slides ()}
%\description
% Inserts the template for new slides.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_insert_slides () {
  insert ("@SysInclude { slides }\n");
  insert ("@OverheadTranspencies\n");
  insert ("@Title {  }\n");
  insert ("@RunningTitle {  }\n");
  insert ("@Author {  }\n");
  insert ("@Institution {  }\n");
  insert ("@DateLine { Yes }\n");
  insert ("@InitialFont { "
		+lout_fonts[LOUT_DEFAULT_FONT]+" "
		+lout_font_faces[LOUT_DEFAULT_FONT_FACE]+" "
		+"20p"+" }\n");
  insert ("#@InitialBreak { adjust 1.2fx hyphen }\n");
  insert ("#@InitialSpace { lout }\n");
  insert ("#@InitialLanguage { English }\n");
  insert ("#@PageOrientation { Portrait }\n");
  insert ("#@PageHeaders { Titles }\n");
  insert ("#@FirstPageNumber { 1 }\n");
  insert ("#@FirstOverheadNumber { 1 }\n");
  insert ("#@FirstLectureNumber { 1 }\n");
  insert ("#@OptimizePages { No }\n");
  insert ("//\n");
  whitespace(LOUT_INDENTATION);
}

%!%+
%\function{lout_insert_illustration}
%\synopsis{Inserts the template for a new illustration}
%\usage{lout_insert_illustration ()}
%\description
% Inserts the template for a new illustration.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_insert_illustration () {
  insert ("@SysInclude { picture }\n");
  insert ("@Illustration\n");
  insert ("@InitialFont { "
		+lout_fonts[LOUT_DEFAULT_FONT]+" "
		+lout_font_faces[LOUT_DEFAULT_FONT_FACE]+" "
		+LOUT_DEFAULT_FONT_SIZE+" }\n");
  insert ("#@InitialBreak { adjust 1.2fx hyphen }\n");
  insert ("#@InitialSpace { lout }\n");
  insert ("#@InitialLanguage { English }\n");
  insert ("#@InitialColour { black }\n");
  insert ("{\n");
  whitespace(LOUT_INDENTATION);
  insert ("\n}\n");
  go_up (2);
  eol ();
}

%!%+
%\function{lout_new_document}
%\synopsis{Inserts the template for a new document style}
%\usage{lout_new_document ()}
%\description
% Asks the user for a document style and inserts the template for a new document.
%\seealso{LOUT_DEFAULT_DOCUMENT, lout_mode}
%!%-
define lout_new_document () {
  variable tmp;


  tmp = strjoin (assoc_get_keys (lout_document_styles),",");

  LOUT_DEFAULT_DOCUMENT = read_with_completion 
    (tmp, "Enter symbol:", LOUT_DEFAULT_DOCUMENT, "", 's');

  switch (lout_last_symbol)
  { LOUT_DEFAULT_DOCUMENT == "document" :
    lout_insert_document ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { LOUT_DEFAULT_DOCUMENT == "report" :
    lout_insert_report ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { LOUT_DEFAULT_DOCUMENT == "book" :
    lout_insert_book ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { LOUT_DEFAULT_DOCUMENT == "slides" :
    lout_insert_slides ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { LOUT_DEFAULT_DOCUMENT == "illustration" :
    lout_insert_illustration ();
  }
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  { % else of switch
    verror ("\"%s\" is not a known `lout' document style.",LOUT_DEFAULT_DOCUMENT);
  }
}
  
%!%+
%\function{lout_insert_space}
%\synopsis{Inserts a space and eventually indents the line}
%\usage{lout_insert_space ()}
%\description
% Inserts a space and indents the line if the previous word begins with
% the char '@'.
%\seealso{lout_mode}
%!%-
define lout_insert_space () {
  push_spot ();
  bskip_word ();
  if (looking_at_char ('@') or looking_at_char('}'))
    indent_line ();
  pop_spot ();
  insert_char(' ');
}


%!%+
%\variable{lout_default_compile_file}
%\synopsis{lout_default_compile_file}
%\description
% Holds the default file which will be compiled with lout.
%\seealso{lout_compile, lout_mode}
%!%-
variable lout_default_compile_file="";

%!%+
%\function{lout_compile}
%\synopsis{Compiles a file with lout}
%\usage{lout_compile ()}
%\description
% Asks for a file to compile with the lout text processor.
%\seealso{lout_default_compile_file, lout_mode}
%!%-
define lout_compile () {
  if (lout_default_compile_file=="")
    lout_default_compile_file=whatbuf ();
  lout_default_compile_file=read_with_completion(strjoin(listdir("."),","),
					      "Lout compile file:",
					      lout_default_compile_file,
					      "",
					      's');
  compile("lout -a -o "+path_sans_extname(lout_default_compile_file)+".ps "+lout_default_compile_file);
}
  
%!%+
%\function{lout_newline}
%\synopsis{Inserts a new line and indents}
%\usage{lout_newline ()}
%\description
% If the current line starts with "@End" indents the line, then inserts
% a new line and moves the point to the current indentation level.
%\seealso{lout_indent_line, newline, lout_mode}
%!%-
define lout_newline () {
  push_spot ();
  bol_skip_white ();
  if (looking_at ("@End"))
    lout_indent_line ();
  pop_spot ();
  newline ();
  lout_indent_line ();
  skip_white ();
}

%!%+
%\function{lout_embrace}
%\synopsis{Surrounds the region with braces}
%\usage{lout_embrace}
%\description
% Surrounds the region, if defined, with curly braces, else inserts a pair
% of curly braces and moves the cursor inbetween.
%\seealso{lout_mode}
%!%-
define lout_embrace () {
  !if (markp ()) {
    insert ("{  }");
    ()=left (2);
    return;
  }
  
  check_region (0);
  exchange_point_and_mark ();
  insert ("{");
  trim ();
  insert (" ");
  exchange_point_and_mark ();
  insert ("}");
  ()=left (2);
  trim ();
  ()=right (1);
  insert (" ");
  ()=right (1);
  pop_mark (0);
}


%!%+
%\function{lout_add_completion_symbol}
%\synopsis{Adds adds a keyword to the list of known keywords}
%\usage{lout_add_completion (String_Type id, String_Type keyword)}
%\description
% Adds adds a keyword to the list of known keywords. The \var{id} string
% should be an easily to type and remember string which identifies the
% keyword uniquely. It is used as the lookup key for the actual keyword 
% in the minibuffer. Usually it is constructed from the keyword by converting
% the keyword to lowercase and removing the preceding '@', but may be an
% arbitrary string, even the empty string.
%\seealso{lout_insert, lout_complete_text, lout_insert_symbol, lout_mode}
%!%-
define lout_add_completion_symbol (id, keyword) {
  if (id != "") {
    lout_key_completions += "," + id;
    lout_symbols[id] = keyword;
  } else {
    lout_symbols["NO KEY"] = keyword;
  }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
%%%% define keys
%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
!if (keymap_p("lout")) {
  make_keymap ("lout");

  definekey_reserved("lout_smart_insert_section()",                   "^s","lout");
  definekey_reserved("lout_new_document",                             "^d","lout");
  definekey_reserved("lout_insert",                                   "^v","lout");
  definekey_reserved("lout_compile",                                  "^c","lout");
  definekey_reserved("lout_insert_font",                              "^f","lout");
  definekey_reserved("compile_parse_errors",                          "^n","lout");
  definekey_reserved("compile_previous_error",                        "^p","lout");
  definekey_reserved("compile_parse_errors",                          "^@","lout");
  definekey_reserved("compile_previous_error",                        "^x","lout");
  definekey_reserved("lout_embrace",                                  "c","lout");
  definekey_reserved("comment_region",                                ";","lout");
  definekey_reserved("comment_region",                                "#","lout");
  definekey_reserved("uncomment_region",                              ":","lout");
  
  definekey("insert_char('{'); indent_line()",                        "{","lout");
  definekey("insert_char('}'); indent_line(); blink_match()",         "}","lout");
  definekey("lout_insert_space",                                      " ","lout");
  definekey("lout_newline",                                           "\r","lout");
  definekey("indent_line(); skip_white()",                            "\t","lout");
  definekey("lout_complete_text",                                     "\e\t","lout");
}


%!%+
%\function{lout_mode}
%\synopsis{Editing mode for `lout' text files}
%\usage{lout_mode}
%\description
% This is an editing mode for the `lout' document formatting language. The following
% keys are defined:
%   ^C^S  :  lout_smart_insert_section
%   ^C^D  :  lout_new_document
%   ^C^V  :  lout_insert
%   ^C^F  :  lout_insert_font   
%   ^C^C  :  lout_compile
%   ^C^@  :  compile_parse_errors
%   ^C^N  :  compile_parse_errors
%   ^C^X  :  compile_previous_error 
%   ^C^P  :  compile_previous_error
%   ^CC   :  lout_embrace
%   ^C;   :  comment_region
%   ^C#   :  comment_region
%   ^C:   :  uncomment_region
%   ^C^I  :  lout_complete_text
%   \e^I  :  lout_complete_text
%   ^I    :  indent_line
%   \r    :  lout_newline
% The reserved prefix key might be different from `^C' if you are not using  emacs
% emulation mode. "^@" is Contol-Space.
%\seealso{LOUT_IGNORE_COMMENT, LOUT_INDENTATION, LOUT_DEFAULT_FONT,
%LOUT_DEFAULT_FONT_SIZE, LOUT_DEFAULT_FONT_FACE, LOUT_DEFAULT_DOCUMENT}
%!%-
define lout_mode ()
{
  set_mode("lout", 1); % +32?
  set_comment_info("lout","# ","",6); % used by comment_region, not for the highlightening
  use_syntax_table ("lout");
  use_dfa_syntax (1);
  set_buffer_hook("par_sep","lout_paragraph_separator");
  set_buffer_hook("indent_hook","lout_indent_line");
  set_buffer_hook("wrap_hook","lout_wrap_hook");
  define_word ("0-9 at A-Za-z??-????-????-??");
  use_keymap ("lout");
  
  compile_select_compiler ("lout");

  run_mode_hooks ("lout_mode_hook");
}


add_completion("lout_mode");
add_completion("indent_region");

% This is an example for adding your own symbol to lout_mode:
%     lout_add_completion_symbol ("mysym", "@MySymbol")



More information about the Jed-users-l mailing list