[#] Konwersja pliku SH do HTML z kolorowaniem składni

( Ostatnio zmieniony pon., 14/07/2008 - 23:45 )
 
#!/bin/sh
# Convert a shell script into HTML, with syntax highlighting
#
# (C) 2004 Kevin Waldron
# Released under the terms of the GNU General Public Licence
#
# Most modern Bourne Shell features are implemented here. Other
# common external commands are also implemented. We can't implement
# everything that may exist in everyones PATH's however!!

if [ "$#" -ne "2" ]; then
  echo "Usage: $(basename $0) filename outputfile" && exit 1
fi

O_FILE=$2

if [ -e "${O_FILE}" ]; then
  echo "$(basename $0): Error: ${O_FILE} already exists" && exit 1
fi

I_FILE=$1

if [ ! -e "${I_FILE}" ]; then
  echo "$(basename $0): Error: ${I_FILE} does not exist" && exit 1
fi

# Print standard header stuff to file

echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">" >> ${O_FILE}

echo "<head>" >> ${O_FILE}
echo "<!-- Generated with sh2html - http://www.zazzybob.com -->" >> ${O_FILE}
echo "<title>$(basename ${I_FILE})</title>" >> ${O_FILE}
echo "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />" >> ${O_FILE}
echo "</head>" >> ${O_FILE}
echo "<body>" >> ${O_FILE}
echo "<pre>" >> ${O_FILE}

# main awk routine - syntax highlighting done here!
awk '{
  # these gsubs globally replace special chars
  gsub( "&", "\\&amp;", $0 );
  gsub( "<", "\\&lt;", $0 );
  gsub( ">", "\\&gt;", $0 );


  commandArray[0] = "awk";
  commandArray[1] = "read";
  commandArray[2] = "exit";
  commandArray[3] = "ls";
  commandArray[4] = "rm";
  commandArray[5] = "sort";
  commandArray[6] = "uniq";
  commandArray[7] = "sed";
  commandArray[8] = "mv";
  commandArray[9] = "cp";
  commandArray[10] = "join";
  commandArray[11] = "grep";
  commandArray[12] = "cat";
  commandArray[13] = "df";
  commandArray[14] = "cd";
  commandArray[15] = "basename";
  commandArray[16] = "id";
  commandArray[17] = "tr";
  commandArray[18] = "ls";
  commandArray[19] = "true";
  commandArray[20] = "false";
  commandArray[21] = "seq";
  commandArray[22] = "cut";
  commandArray[23] = "getopt";
  commandArray[24] = "getopts";
  commandArray[25] = "gunzip";
  commandArray[26] = "gzip";
  commandArray[27] = "tar";
  commandArray[28] = "date";
  commandArray[29] = "clear";
  commandArray[30] = "ps";
  commandArray[31] = "ifconfig";
  commandArray[32] = "ping";
  commandArray[33] = "tput";
  commandArray[34] = "useradd";
  commandArray[35] = "passwd";
  commandArray[36] = "stty";
  commandArray[37] = "chown";
  commandArray[38] = "chmod";
  commandArray[39] = "trap";
  commandArray[40] = "sleep";
  commandArray[41] = "wait";
  commandArray[42] = "last";
  commandArray[43] = "head";
  commandArray[44] = "let";
  commandArray[45] = "shift";
  commandArray[46] = "unalias";
  commandArray[47] = "read";
  commandArray[48] = "unset";
  commandArray[49] = "alias";
  commandArray[50] = "expr";
  commandArray[51] = "printf";
  commandArray[52] = "mkdir";
  commandArray[53] = "declare";
  commandArray[54] = "local";
  commandArray[55] = "tail";
  commandArray[56] = "hostname";
  commandArray[57] = "xterm";
  commandArray[58] = "bc";
  commandArray[59] = "wc";
  commandArray[60] = "more";
  commandArray[61] = "find";
  commandArray[62] = "mount";
  commandArray[63] = "who";
  commandArray[64] = "suspend";
  commandArray[65] = "ulimit";
  commandArray[66] = "umask";
  commandArray[67] = "source";
  commandArray[68] = "bind";
  commandArray[69] = "builtin";
  commandArray[70] = "typeset";
  commandArray[71] = "export";
  commandArray[72] = "fc";
  commandArray[73] = "history";
  commandArray[74] = "hash";
  commandArray[75] = "jobs";
  commandArray[76] = "kill";
  commandArray[77] = "fg";
  commandArray[78] = "bg";
  commandArray[79] = "logout";
  commandArray[80] = "popd";
  commandArray[81] = "pushd";
  commandArray[82] = "pwd";
  commandArray[83] = "shopt";
  commandArray[84] = "test";
  commandArray[85] = "touch";

  # update array_length manually below!
  array_length = 85;

  # deal with comments first - ignore entire line if one is found
  if ( $0 ~ /^[   ]*#/ ) {
    print "<span style=\"color: green\"><i>"$0"</i></span>";
  }
  else {
    # syntax highlight on a line-by-line, element-by-element basis
    # dealing with echo firstly, so we can say echo "echo if else"
    # and only have the "echo" highlighted

    if ( $0 ~ /^[   ]*echo/ ) {
      gsub( /^[   ]*echo/, "<strong>&</strong>", $0 );
      gsub( /;[   ]*echo/, "; <strong>echo</strong>", $0 );

      # check for commands within ` and ( in echo
      for ( i = 0; i <= array_length; i++ ) {
        x=commandArray[i];

        if ( $0 ~ x ) {
          reg = "[(]"x"[   ]*";
          gsub( reg, "(<strong>"x"</strong> ", $0 );
          reg = "[(][ ]+"x"[   ]+";
          gsub( reg, "( <strong>"x"</strong> ", $0 );
          reg = "[`]"x"[   ]*";
          gsub( reg, "`<strong>"x"</strong> ", $0 );
          reg = "[`][ ]+"x"[   ]+";
          gsub( reg, "` <strong>"x"</strong> ", $0 );
          reg = "^[   ]*"x"[   ]*$";
          gsub( reg, "<strong>&</strong>", $0 );
          reg = "[ ]+"x"[   ]+";
          gsub( reg, "<strong>&</strong>", $0 );
       }
     }
    }
    else {
      # catch other echos - i.e. with case
      gsub( /[   ]*echo[   ]+/, "<strong>&</strong>", $0 );

      # if - will be at start of line (usually)
      gsub( /if test/, "<span style=\"color: blue\"><strong>if</strong></span> <strong>test</strong>", $0 );
      gsub( /^[   ]*if[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /^[   ]*if[   ]*$/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );


      # else - will be at start of line (usually)
      gsub( /^[   ]*else[   ]*$/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # elif - will be at start of line (usually)
      gsub( /^[   ]*elif[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # fi - will also usually be at the start of a line
      gsub( /^[   ]*fi[   ]*$/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # for - will be at start of line (usually)
      gsub( /^[   ]*for[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # select - will be at start of line (usually)
      gsub( /^[   ]*select[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # while - will be at start of line (usually)
      gsub( /while read/, "<span style=\"color: blue\"><strong>while</strong></span> <strong>read</strong>", $0 );

      gsub( /^[   ]*while[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );


      # until - will be at start of line (usually)
      gsub( /^[   ]*until[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # case - will be at start of line (usually)
      gsub( /^[   ]*case[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # esac - will be at start of line (usually)
      gsub( /^[   ]*esac[   ]*$/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # function - will be at start of line (usually)
      gsub( /^[   ]*function[   ]+/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # done - will be at start of line (usually)
      gsub( /^[   ]*done[   ]*/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );

      # then - can be at start of line, or after a ;
      gsub( /^[   ]*then[   ]*$/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /;[   ]*then[   ]*$/, "; <span style=\"color: blue\"><strong>then</strong></span>", $0 );

      # special case - then followed by comment
      if ( /[   ]*then[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /then/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - do followed by comment
      if ( /[   ]*do[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /do/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

         # special case - else followed by comment
      if ( /[   ]*else[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /else/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - break followed by comment
      if ( /[   ]*break[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /break/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - continue followed by comment
      if ( /[   ]*continue[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /continue/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - done followed by comment
      if ( /[   ]*done[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /done/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - fi followed by comment
      if ( /[   ]*fi[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /fi/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # special case - esac followed by comment
      if ( /[   ]*esac[   ]*#/ ) {
        gsub( /[^$]#.*$/, "<span style=\"color: green\"><i>&</i></span>", $0 );
        gsub( /esac/, "<span style=\"color: blue\"><strong>&</strong></span>", $0 );
      }

      # do - can be at start of line, or after a ;
      gsub( /^[   ]*do[   ]*$/, " <span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /;[   ]*do[   ]*$/, "; <span style=\"color: blue\"><strong>do</strong></span>", $0 );

      # continue - can be at start of line, or after a ;
      gsub( /^[   ]*continue[   ]*$/, " <span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /;[   ]*continue[   ]*$/, "; <span style=\"color: blue\"><strong>continue</strong></span>", $0 );
      gsub( /continue;/, " <span style=\"color: blue\"><strong>continue</strong></span>;", $0 );

      # break - can be at start of line, or after a ; or ending in ;
      gsub( /^[   ]*break[   ]*$/, " <span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /;[   ]*break[   ]*$/, "; <span style=\"color: blue\"><strong>break</strong></span>", $0 );
      gsub( /break[ ]*;/, " <span style=\"color: blue\"><strong>break</strong></span> ;", $0 );

      # return - can be at start of line, or after a ;
      gsub( /^[   ]*return[   ]*/, " <span style=\"color: blue\"><strong>&</strong></span>", $0 );
      gsub( /;[   ]*return[   ]*/, "; <span style=\"color: blue\"><strong>return</strong></span>", $0 );

      # scan for more comments - probably makes some of the code
      # above redundant! A bit of a "catch all" for comments that
      # slip through the net.
      if ( /[^${#]#[^#]/ ) {
        gsub( /[^$^]#.*$/, " <span style=\"color: green\"><i>&</i></span>", $0 );
      }

      # exec - special case as more commands may follow it
      if ( /[^#][  ]*exec[    ]*/ ) {
        gsub( /exec/, "<strong>&</strong>", $0 );
      }
      if ( /^exec/ ) { gsub ( /exec/, "<strong>exec</strong>", $0 ); }


      # eval - special case as more commands may follow it
      if ( /[^#][  ]*eval[    ]*/ ) {
        gsub( /eval/, "<strong>&</strong>", $0 );
      }

      # set - to allow tput reset
      if ( /set/ ) {
        gsub( /^[  ]*set/, "<strong>&</strong>", $0 );
      }

      for ( i = 0; i <= array_length; ++i ) {
       x = commandArray[i];

       if ( $0 ~ x ) {
         reg = "[(]"x"[   ]*";
         gsub( reg, "(<strong>"x"</strong> ", $0 );
         reg = "[(][ ]+"x"[   ]+";
         gsub( reg, "( <strong>"x"</strong> ", $0 );
         reg = "[`]"x"[   ]*";
         gsub( reg, "`<strong>"x"</strong> ", $0 );
         reg = "[\047]"x"[   ]*";
         gsub( reg, "\047<strong>"x"</strong> ", $0 );
         reg = "[\042]"x"[   ]*";
         gsub( reg, "\042<strong>"x"</strong> ", $0 );
         reg = "[`][ ]+"x"[   ]+";
         gsub( reg, "` <strong>"x"</strong> ", $0 );
         reg = "[   ]+"x"[   ]+";
         gsub( reg, "<strong>&</strong>", $0 );
         reg = x";";
         gsub( reg, "<strong>"x"</strong>;", $0 );
         reg = "^[   ]*"x"[   ]+";
         gsub( reg, "<strong>&</strong>", $0 );
         reg = "[ ]*"x"[`]";
         gsub( reg, " <strong>"x"</strong>`", $0 );
         reg = "[ ]*"x"[)]";
         gsub( reg, " <strong>"x"</strong>)", $0 );
         reg = "[ ]*"x"[ ]+[`]";
         gsub( reg, " <strong>"x"</strong> `", $0 );
         reg = "[ ]*"x"[ ]+[)]";
         gsub( reg, " <strong>"x"</strong> )", $0 );
         reg = "^[   ]*"x"[   ]*$";
         gsub( reg, "<strong>&</strong>", $0 );
         reg = "[|][ ]+"x;
         gsub( reg, "| <strong>"x"</strong>", $0 );
       }
      }

      # some comparison ops
      gsub( /[   ]+\-gt[   ]+/, " <strong>-gt</strong> ", $0 );
      gsub( /[   ]+\-lt[   ]+/, " <strong>-lt</strong> ", $0 );
      gsub( /[   ]+\-eq[   ]+/, " <strong>-eq</strong> ", $0 );
      gsub( /[   ]+\-ne[   ]+/, " <strong>-ne</strong> ", $0 );
      gsub( /[   ]+\-ge[   ]+/, " <strong>-ge</strong> ", $0 );
      gsub( /[   ]+\-le[   ]+/, " <strong>-le</strong> ", $0 );
      gsub( /[   ]+\-a[   ]+/, " <strong>-a</strong> ", $0 );
      gsub( /[   ]+\-o[   ]+/, " <strong>-o</strong> ", $0 );
      gsub( /[   ]+\-n[   ]+/, " <strong>-n</strong> ", $0 );
      gsub( /[   ]+\![   ]+/, "<strong> !</strong> ", $0 );
      gsub( /[   ]+\-e[   ]+/, " <strong>-e</strong> ", $0 );
      gsub( /[   ]+\-z[   ]+/, " <strong>-z</strong> ", $0 );
      gsub( /[   ]+\-f[   ]+/, " <strong>-f</strong> ", $0 );
    }

    # print out the line now we are all gsubbed
    print $0
  }
}' ${I_FILE} >> ${O_FILE}

# print website plug - please leave in to "spread the word"
echo "<br /><br />" >> ${O_FILE}
echo "<span style=\"color: green\"><i># Generated with sh2html - freely available from http://www.zazzybob.com/sh2html.html</i></span>" >> ${O_FILE}

# print standard footer stuff to file

echo "</pre>" >> ${O_FILE}
echo "</body>" >> ${O_FILE}
echo "</html>" >> ${O_FILE}

exit 0
5
Twoja ocena: Brak Średnio: 5 (1 vote)