#

function underline(s)
{
 gsub(/./,"_&",s); 
 return s;
}


function header(s)
{
  print "\n";
  print underline(sprintf("%d. %s", ++count,s)) "\n";
}


BEGIN { operation =  ARGV[2]; 
        type = ARGV[1];
        gsub(/\/.*\//, "",type);
        gsub(/\.tex/, "",type);
        ARGV[2] = ""; 
        gsub(/_/, "\\_", operation); print " "; 
        op_header = 0;
       }


/\{\\magonebf/ { 
if (operation == "" || "definition" == operation)
{ gsub(/\{\\magonebf /, "");
  gsub(/\}/, "");
  gsub(/\\/, "");
  print underline($0);
  print " ";
   if (operation == "") header("DEFINITION");
    getline;
    while ($1 == "") getline;
    while ($1 !~ "skip" && $1 != "")
      { gsub(/\\{/,"kl_auf");
        gsub(/\\}/,"kl_zu");
        gsub(/{/,"");
        gsub(/}/,"");
        gsub("kl_auf", "{");
        gsub("kl_zu", "}");
        gsub(/\$/,"");
        gsub(/\\longrightarrow/, "---->");
        gsub(/\\times/, " x");
        gsub(/\\dots/, "...");
        gsub(/\\cdot/, " *");
        gsub(/\\le/,   " <=");
        gsub(/\\ge/,   " >=");
        gsub(/\\neq/,  " !=");
        gsub(/\\ne/,   " !=");
        gsub(/\\/, "");
        gsub(/backslash/, "\\");
        print;
        getline; 
       }
    print " ";
  }
}

/\\decl/ { 
if (operation == "" || "declaration" == operation) 
{ 
  if (operation == "") header("DECLARATION");

  gsub(/\\/, "");
  if ($1 == "decl")
    { printf("declare(%s,%s)\n\n",$2,$3);
      type = $2"("$3")";
     }
  else
     if ($1 == "decltwo")
     { printf("declare2(%s,%s,%s)\n\n",$2,$3,$4);
       type = $2"("$3","$4")";
      }
     else
        if ($1 == "declthree")
        { printf("declare3(%s,%s,%s,%s)\n\n",$2,$3,$4,$5);
          type = $2"("$3","$4","$5")";
         }

  getline;
  while ($1 == "") getline;
  while ($1 !~ "skip" && $1 != "")
    { gsub(/\\{/,"kl_auf");
      gsub(/\\}/,"kl_zu");
      gsub(/{/,"");
      gsub(/}/,"");
      gsub("kl_auf", "{");
      gsub("kl_zu", "}");
      gsub(/\$/,"");
      gsub(/\\name/,type);
      gsub(/\\/,"");
      print;
      getline; 
     }
  print " ";
}
}

/\\create/ { 
  out = 0;
  if (operation == "" || "creation" == operation) 
  { out = 1
    if (operation == "") header("CREATION");
   }

  while ($0 ~ "\\\\create") 
  { i = 1;
    while ($i != "\\create") i++;
    i++;
    var = $i; 
    gsub(/\\create/, type);
    gsub(/\{\}/, "");
    gsub(/\\/, "");
    if (out==1) printf("%s;\n\n",$0);
    getline;
    while ($1 == "") getline;
  }


  if (out==1) 
  { while ($1 !~ "skip" && $1 != "")
    { gsub(/{/,"");
      gsub(/}/,"");
      gsub(/\$/,"");
      gsub(/\\name/,type);
      gsub(/\\var/,var);
      gsub(/\\precond/, "Precondition:");
      gsub(/\\/,"");
      print;
      getline; 
     }
   print " ";
  }
}


#operations & operators: line starts with \+\op

/\\\+\\op/ {
if ($3 == operation || operation == "" || "operations" == operation)
{ 
  if (op_header==0) { if (operation == "") header("OPERATIONS"); 
                      op_header=1; 
                     }
  gsub(/\\/,"");
  gsub(/}/,"");
  gsub(/{/,"");
  gsub(/\$/,"");
  gsub(/tilde/,"\~");

  if ($1 == "+op") #operation
   { printf("%-9s %s.%s (",$2,var,$3);
     for (i=4;i<=NF;i++) printf("%s ",$i);
     if ($1 == "+op") printf(")");
    }
  else
     if ($1 == "+opb") #binary operator
      { printf("%-9s %s ",$2,var);
        for (i=3;i<=NF;i++) printf("%s ",$i);
       }
     else  
        if ($1 == "+ops") #stream operator
         { printf("%-9s %s %s %s",$2,$4,$3,var);
           for (i=5;i<=NF;i++) printf("%s ",$i);
          }
        else
           if ($1 == "+opf") #function call operator
           { printf("%-9s %s (",$2,var);
             for (i=3;i<NF;i++) printf("%s ",$i);
             printf("%s)",$i);
            }
           else
             if ($1 == "+opu") #unary operator
               printf("%-9s %s%s",$2,$3,var);
             else
             if ($1 == "+opa") #array access operator
               printf("%-9s %s [%s %s]",$2,var,$3,$4);

  print " ";
  getline;
  if ("operations" != operation)
  { print " ";
    while ($1 !~ "skip" && $1 != "")
    { start = 1;
      if ($1 == "\\+\\nop") start = 2;
      printf("                      ");
      gsub(/\\precond/,"Precondition:");
      gsub(/\\{/,"kl_auf");
      gsub(/\\}/,"kl_zu");
      gsub(/{/,"");
      gsub(/}/,"");
      gsub("kl_auf", "{");
      gsub("kl_zu", "}");
      gsub(/\$/,"");
      gsub(/\\var/, var);
      gsub(/\\longrightarrow/, "---->");
      gsub(/\\times/, " x");
      gsub(/\\phantom/, "");
      gsub(/\\dots/, "...");
      gsub(/\\cdot/, " *");
      gsub(/\\le/,   " <=");
      gsub(/\\ge/,   " >=");
      gsub(/\\neq/,  " !=");
      gsub(/\\ne/,   " !=");
      gsub(/\\/, "");
      gsub(/backslash/, "\\");
      for (i=start;i<=NF;i++) printf("%s ",$i);
      print " ";
      getline; 
     }
   print " ";
  }
}
}

/Iteration/ { 
if (operation == "" || "iteration" == operation) 
{ if (operation == "") header("ITERATION");
  getline;
  while ($1  ~ "skip" || $1 == "") getline;
  while ($1 !~ "skip")
    { gsub(/\\{/,"kl_auf");
      gsub(/\\}/,"kl_zu");
      gsub(/{/,"");
      gsub(/}/,"");
      gsub("kl_auf", "{");
      gsub("kl_zu", "}");
      gsub(/\$/,"");
      gsub(/\\dots/, "...");
      gsub(/\\bf /, "");
      gsub(/\\nl/, "");
      gsub(/\\/, "");
      print;
      getline; 
      while ($1 ~ "phantom" || $1 == "") getline;
     }
  print " ";
}
}

/Implementation/ { 
if (operation == "" || "implementation" == operation) 
{ if (operation == "") header("IMPLEMENTATION");
  getline;
  while ($1  ~ "skip" || $1 == "") getline;
  while ($1 !~ "skip" && $1 != "")
    { gsub(/{/,"");
      gsub(/}/,"");
      gsub(/\$/,"");
      gsub(/\\times/, " x");
      gsub(/\\dots/, "...");
      gsub(/\\cdot/, " *");
      gsub(/\\le/,   " <=");
      gsub(/\\/,"");
      print;
      getline; 
     }
  print " ";
}
}
