% File:          latex_conv.sl                       -*- mode: SLang -*-
%
% Copyright (c)
%       2006--2007  Jörg Sommer <joerg@alea.gnuu.de>
%       $Id$
%
%       -*- This file is part of Jörg's LaTeX Mode (JLM) -*-
%
% Description:   This file include functions to convert LaTeX stuff into
%                each other like "a to ä or : to \colon
%
% License: This program is free software; you can redistribute it and/or
%	   modify it under the terms of the GNU General Public License as
%	   published by the Free Software Foundation; either version 2 of
%	   the License, or (at your option) any later version.
%
%          This program is distributed in the hope that it will be
%	   useful, but WITHOUT ANY WARRANTY; without even the implied
%	   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
%	   PURPOSE.  See the GNU General Public License for more details.

if (length(where("latex_conv" == _get_namespaces())))
  use_namespace("latex_conv");
else
  implements("latex_conv");

autoload("Global->enable_stack_check", "stkcheck");
try
{
    enable_stack_check();
}
catch OpenError: {} % stkcheck not found in the path

define german_utf8()
{
    while ( fsearch_char('"') )
    {
        if ( blooking_at("\\") )
          continue;

        () = right(1);
        variable new;
        switch ( what_char() )
        { case 'a': new = "ä"; }
        { case 'A': new = "Ä"; }
        { case 'o': new = "ö"; }
        { case 'O': new = "Ö"; }
        { case 'u': new = "ü"; }
        { case 'U': new = "Ü"; }
        { case 's': new = "ß"; }
        { case '`' or case '\'': continue; }
        { throw ApplicationError, "Unkown sequence: \""+char(what_char()); }

        () = left(1);
        () = replace_chars(2, new);
    }
}

define german_lat1()
{
    while ( fsearch_char('"') )
    {
        % fixme: latex->is_escaped latex->is_commented
        if (blooking_at("\\") or parse_to_point() == -2)
        {
            () = right(1);
            continue;
        }

        () = right(1);
        variable new;
        switch ( what_char() )
        { case 'a': new = "ä"; }
        { case 'A': new = "Ä"; }
        { case 'o': new = "ö"; }
        { case 'O': new = "Ö"; }
        { case 'u': new = "ü"; }
        { case 'U': new = "Ü"; }
        { case 's': new = "ß"; }
        { case '`' or case '\'': continue; }
        { throw ApplicationError, "Unkown sequence: \""+char(what_char()); }

        () = left(1);
        () = replace_chars(2, new);
    }
}

define native_lat1()
{
    push_spot();
    try
    {
        while ( fsearch("\\\"") )
        {
            if ( blooking_at("\\") )
              continue;

            () = right(2);
            variable new;
            switch ( what_char() )
            { case 'a': new = "ä"; }
            { case 'A': new = "Ä"; }
            { case 'o': new = "ö"; }
            { case 'O': new = "Ö"; }
            { case 'u': new = "ü"; }
            { case 'U': new = "Ü"; }
            { throw ApplicationError, "Unkown sequence"; }

            () = left(2);
            () = replace_chars(3, new);
        }

        pop_spot(); push_spot(); replace("\\3", "ß");
        pop_spot(); push_spot(); replace("\\ss ", "ß");
        pop_spot(); push_spot(); replace("\\ss{}", "ß");
    }
    finally
      pop_spot();
}

define native_utf8()
{
    push_spot();
    try
    {
        while ( fsearch("\\\"") )
        {
            if ( blooking_at("\\") )
              continue;

            () = right(2);
            variable new;
            switch ( what_char() )
            { case 'a': new = "ä"; }
            { case 'A': new = "Ä"; }
            { case 'o': new = "ö"; }
            { case 'O': new = "Ö"; }
            { case 'u': new = "ü"; }
            { case 'U': new = "Ü"; }
            { throw ApplicationError, "Unkown sequence"; }

            () = left(2);
            () = replace_chars(3, new);
        }

        pop_spot(); push_spot();; replace("\\3", "ß");
        pop_spot(); push_spot();; replace("\\glqq", "„");
        pop_spot(); push_spot();; replace("\\grqq", "“");
        pop_spot(); push_spot();; replace("\\glq", "‚");
        pop_spot(); push_spot();; replace("\\grq", "‘");
    }
    finally
      pop_spot();
}

define colon()
{
    try
    {
        while ( fsearch_char(':') )
        {
            if ( andelse {not looking_at(":=")} {not blooking_at("=")}
                 {not re_looking_at(": *\\[Ll]eftrightarrow"R)}
                 {not re_looking_at(": *\\[Ll]ongleftrightarrow"R)}
                 {not blooking_at("\\")} {latex->is_math()} )
            {
                try
                {
                    push_visible_mark();
                    () = right(1);
                    switch ( get_y_or_n("Replace this : by \\colon") )
                    { case 1:
                        () = left(1);
                        () = replace_chars(1, "\\colon");
                        variable ch = what_char();
                        if ( ('A' <= ch and ch <= 'Z') or
                             ('a' <= ch and ch <= 'z') )
                          insert_char(' ');
                    }
                }
                finally
                  pop_mark(0);
            }
            else
              () = right(1);
        }
    }
    catch UserBreakError;
}

define ltx209_ltx2e()
{
    % Fixme: {\bf \tt } is replaced by \textbf\texttt{}
    % Fixme: PCRE
    while ( latex->search_not_commented(&re_fsearch, "\\[beirst][cflmt]"R, 1) )
    {
        variable mark = create_user_mark();
        () = right(1);
        push_mark();
        skip_chars(latex->TeX_Command_Chars);

        variable short, long;
        switch ( bufsubstr() )
        { case "bf": short = "textbf"; long = "bfseries"; }
        { case "em": short = "emph"; }
        { case "it": short = "textit"; long = "itshape"; }
        { case "rm": short = "textrm"; long = "rmfamily"; }
        { case "sc": short = "textsc"; long = "scshape"; }
        { case "sl": short = "textsl"; long = "slshape"; }
        { case "tt": short = "texttt"; long = "ttfamily"; }
        { continue; }

        skip_chars(" \t\n{}");
        push_mark();
        goto_user_mark(mark);
        del_region();

        () = left(1);
        if ( looking_at_char('{') and not latex->is_escaped() )
        {
            insert("\\"+ short);
            push_spot();
            latex->fsearch_matching_brace();
            if ( left(1) and looking_at_char('/') and latex->is_escaped() )
            {
                () = left(1);
                deln(2);
            }
            pop_spot();
        }
        else
        {
            () = right(1);
            % Fixme: Check for \par and use long form
            % push_mark();
            % latex->fsearch_matching_brace();

            insert("\\" + long + " ");
        }
    }
}