#line 1692 "/home/travis/build/felix-lang/felix/src/packages/flx_web.fdoc"
  
  // Python
  module Py2Html {
  private val big_keywords =
    "def",
    "class",
    "import"
  ;
  private val small_keywords =
    "if", "while", "for", "return", "in", "from","else","elsif","except","try",
    "not","with","raise"
  ;
  
  private val qualifiers =
    "None", "True", "False", "pass","self"
  ;
  
  
  fun xlat_py(t:string, dir:string) : bool * string =
  {
    var out = "";
    proc write_string(t:string)
    {
     out += t;
    }
  
    union state_t =
      | sot // start of token
      | id // processing identifier
      | num // in a number
      | sq // processing single quote string
      | dq // processing double quote string
      | sq3 // processing single quote string
      | dq3 // processing double quote string
      | cppcomment // a C++ style comment
    ;
    fun str(s:state_t) => match s with
    | #sot => "sot"
    | #id => "id"
    | #num => "num"
    | #sq => "sq"
    | #dq => "dq"
    | #sq3 => "sq3"
    | #dq3 => "dq3"
    | #cppcomment => "cppcomment"
    endmatch;
  
    var i = 0; var s:state_t;
    var ch = t.[i];
    proc next() { ch = t.[i]; ++i; }
    fun ahead (j:int)=> t.[i + j - 1];
    fun issq3() =>
      ch == char "'" and
      ahead(1) == char "'" and
      ahead(2) == char "'"
    ;
    fun isdq3() =>
      ch == char '"'  and
      ahead(1) == char '"' and
      ahead(2) == char '"'
    ;
  
    var b = "";
    var last_id = "";
    var last_op = "";
    proc cp() { b += ch; }
    proc ws() {
       write_string('<span class=fstring>'+b+"</span>");
    }
    proc w() {
      //println$ "Token["+str s+"]="+b;
      match s with
      | #dq =>  ws;
      | #sq =>  ws;
      | #sq3 =>  ws;
      | #dq3 =>  ws;
      | #cppcomment => write_string('<span class=comment>'+b+"</span>");
      | #id =>
          last_id = b;
          if b in big_keywords do write_string('<span class=big_keyword>'+b+"</span>");
          elif b in small_keywords do write_string('<span class=small_keyword>'+b+"</span>");
          elif b in qualifiers do write_string('<span class=qualifier>'+b+"</span>");
          else write_string(b); done
      | _ =>
          last_op=b;
          if b == "<" do b = "&lt;";
          elif b == ">" do b = "&gt;";
          elif b == "&" do b = "&amp;";
          done;
          write_string(b);
      endmatch;
      b = "";
    }
  
  
    goto nextt;
  
  contin:> // copy char and continue
    cp();
    goto nextch;
  
  overrun:> // one past last char of token
    w();
    s = sot;
    goto thisch;
  
  lastch:> // last char of token
    cp();
    w();
  
  nextt:>  // new token on next char
    s = sot;
  
  nextch:> // next char
    next();
  
  thisch:> // same char, reconsider it
    //println$ "Considering char " + str(ord(ch));
    if isnull ch goto fin; // out of data
    match s with
    | #sot =>
        if isidstart ch do s = id; goto contin;
        elif isdigit ch do s = num; goto contin;
        elif issq3() do cp; next; cp; next; s = sq3; goto contin;
        elif isdq3() do cp; next; cp; next; s = dq3; goto contin;
        elif issq ch do s = sq; goto contin;
        elif isdq ch do s = dq; goto contin;
        elif ch == char "#" do s = cppcomment; goto contin;
        else cp; w; goto nextt;
        done
  
    | #id =>
        if isalphanum ch do goto contin;
        else goto overrun;
        done
    | #num =>
        if isnumeric ch do goto contin;
        else goto overrun;
        done
    // single quoted strings
    | #sq =>
        if issq ch do goto lastch;
        elif ch== char "<" do b+="&lt;"; goto nextch;
        elif ch== char ">" do b+="&gt;"; goto nextch;
        elif ch== char "&" do b+="&amp;"; goto nextch;
        else goto contin;
        done
    | #dq =>
        if isdq ch do goto lastch;
        elif ch== char "<" do b+="&lt;"; goto nextch;
        elif ch== char ">" do b+="&gt;"; goto nextch;
        elif ch== char "&" do b+="&amp;"; goto nextch;
        else goto contin;
        done
     // triple quoted strings
    | #sq3 =>
        if issq3() do cp; next; cp; next; cp; w; goto nextt;
        elif ch== char "<" do b+="&lt;"; goto nextch;
        elif ch== char ">" do b+="&gt;"; goto nextch;
        elif ch== char "&" do b+="&amp;"; goto nextch;
        else goto contin;
        done
    | #dq3 =>
        if isdq3() do cp; next; cp; next; cp; w; goto nextt;
        elif ch== char "<" do b+="&lt;"; goto nextch;
        elif ch== char ">" do b+="&gt;"; goto nextch;
        elif ch== char "&" do b+="&amp;"; goto nextch;
        else goto contin;
        done
     // comments
    | #cppcomment =>
        if iseol ch do goto lastch;
        else goto contin;
        done
    endmatch
    ;
    println$ "Unexpected drop thru";
  
  fin:>
     println "outof data";
     w(); // whatever is left over gets written
     return false, out;
  }
  }
  
  eprintln$ Version::felix_version+"Py2html initialisation";
  
  fun setup(x:string) = {
    C_hack::ignore(x); // which means, don't ignore it .. :)
    return 0;
  }
  
  export fun setup of (string) as "py2html_setup";
  export fun Py2Html::xlat_py of (string * string) as "py2html";