2014-09-02 92 views
0

因此,我有一個工具,用戶可以將用戶上傳SVN .patch文件。與其單獨下載和查看它,我希望能夠通過紅色的綠色設計直接在線觀看。將.patch轉換爲HTML格式輸出,以便在線觀看

補丁文件[/uploads/Bug123.patch]

### Eclipse Workspace Patch 1.0 
Index: src/main/java/com/admin/Screen.java 
=================================================================== 
--- src/main/java/com/admin/Screen.java (revision 2) 
+++ src/main/java/com/admin/Screen.java (working copy) 
@@ -147,20 +147,22 @@ 
-  System.out.println("Hello World"); 
+  System.out.println("Hello New World"); 

可視[/viewer.php?file=Bug123.patch]

<html><style>.red {background:lightcoral} .green {background:greenyellow} .yellow {background:yellow; font-weight:bold}</style><pre> 
### Eclipse Workspace Patch 1.0 
Index: src/main/java/com/admin/Screen.java 
=================================================================== 
<span class="yellow">--- src/main/java/com/admin/Screen.java (revision 2)</span> 
<span class="yellow">+++ src/main/java/com/admin/Screen.java (working copy)</span> 
@@ -147,20 +147,22 @@ 
<span class="red">-  System.out.println("Hello World"); </span> 
<span class="green">+  System.out.println("Hello New World"); </span> 
</pre></html> 
+0

你的問題是什麼? – scragar 2014-09-02 12:22:59

+0

@scragar如何做到這一點?以補丁文件作爲輸入和輸出HTML – 2014-09-02 13:00:16

回答

1

你可以試試沿線的東西:

<?php 

$file = __DIR__ . '/foo.patch'; 

echo '<doctype html> 
<html> 
<head> 
<style> 
.header { 
    color: black; 
} 
.header-comment { 
    color: grey; 
} 
.file-input, .file-change { 
    color: green; 
} 
.file-output { 
    color: blue; 
} 
.file-line-nos { 
    color: blue; 
} 
.line-context { 
    color: darkgrey; 
} 
.line-add { 
    color: green; 
} 
.line-change { 
    color: yellow; 
} 
.line-del { 
    color: red; 
} 
</style> 
</head> 
<body> 
'; 


echo PatchParser::file_to_html($file); 

echo '</body></html>'; 

class PatchParser { 
    const MODE_HEADER = 1; 
    const MODE_FILE = 2; 

    const LINE_TYPE_HEADER  = 0x0001; 
    const LINE_TYPE_COMMENT  = 0x0002; 
    const LINE_TYPE_FILE_IN  = 0x1001; 
    const LINE_TYPE_FILE_OUT  = 0x1002; 
    const LINE_TYPE_FILE_CHANGE = 0x1003; 
    const LINE_TYPE_LINE_NUMBERS = 0x1004; 
    const LINE_TYPE_CONTEXT  = 0x2001; 
    const LINE_TYPE_ADDITION  = 0x2002; 
    const LINE_TYPE_DELETION  = 0x2003; 
    const LINE_TYPE_CHANGE  = 0x2004; 

    const MARKER_IN_FILE    = '+++'; 
    const MARKER_CHANGED_FILE   = '***'; // Used for context diffs 
    const MARKER_OUT_FILE    = '---'; 
    const MARKER_FILE_LINE_NUMBERS  = '@'; 
    const MARKER_HEADER_COMMENT  = '#'; 
    const MARKER_FILE_CHANGE   = '!'; 
    const MARKER_FILE_NORMAL_ADDITION = '>'; 
    const MARKER_FILE_NORMAL_DELETION = '<'; 
    const MARKER_FILE_UNIFIED_ADDITION = '+'; 
    const MARKER_FILE_UNIFIED_DELETION = '-'; 


    static public function file_to_html($file){ 
     return self::text_to_html(file_get_contents($file)); 
    } 

    static public function text_to_html($contents){ 
     $parsed_lines = self::parse($contents); 

     $classes = array(
     self::LINE_TYPE_HEADER  => 'header header-text', 
     self::LINE_TYPE_COMMENT  => 'header header-comment', 
     self::LINE_TYPE_FILE_IN  => 'file file-input', 
     self::LINE_TYPE_FILE_OUT  => 'file file-output', 
     self::LINE_TYPE_FILE_CHANGE => 'file file-change', 
     self::LINE_TYPE_LINE_NUMBERS => 'file file-line-nos', 
     self::LINE_TYPE_CONTEXT  => 'line line-context', 
     self::LINE_TYPE_ADDITION  => 'line line-add', 
     self::LINE_TYPE_DELETION  => 'line line-del', 
     self::LINE_TYPE_CHANGE  => 'line line-change' 
    ); 

     $no_lines = count($parsed_lines); 
     $lines_width = strlen("$no_lines"); 

     $output = '<pre>'; 
     foreach ($parsed_lines AS $line_no => $line){ 
     ++$line_no; 
     $output .= str_pad($line_no, $lines_width, " ", STR_PAD_LEFT) 
      . ' ' 
      . '<span class="' 
      . $classes[$line[1]] 
      . '">' 
      . htmlspecialchars($line[0]) 
      . '</span><br />'; 
     } 
     return $output . '</pre>'; 
    } 

    static public function parse($contents) { 
     $lines = explode("\n", $contents); 
     $output = array(); 

     $mode = self::MODE_HEADER;// Stay's in header mode until we encounter a file handle 
     foreach ($lines AS $line) { 
     // trim the line to remove excess whitespace, then test the prefix 
     $trimmed_line = trim($line); 
     $first_three_chars = substr($trimmed_line,0,3); 

     // The types that can occur in both modes are the file names/types 
     if ($first_three_chars === self::MARKER_IN_FILE) { 
      $output[] = array($line, self::LINE_TYPE_FILE_IN); 
      $mode = self::MODE_FILE; 
      continue; 
     } 

     if ($first_three_chars === self::MARKER_CHANGED_FILE) { 
      $output[] = array($line, self::LINE_TYPE_FILE_CHANGE); 
      $mode = self::MODE_FILE; 
      continue; 
     } 

     if (substr($trimmed_line,0,3) === self::MARKER_OUT_FILE) { 
      $output[] = array($line, self::LINE_TYPE_FILE_OUT); 
      $mode = self::MODE_FILE; 
      continue; 
     } 

     // Otherwise our mode is important: 
     if ($mode === self::MODE_HEADER){ 
      // Header mode only supports header text and comments: 
      if (substr($trimmed_line, 0, 1) === self::MARKER_HEADER_COMMENT) { 
       $output[] = array($line, self::LINE_TYPE_COMMENT); 
      } else { 
       $output[] = array($line, self::LINE_TYPE_HEADER); 
      } 
      continue; 
     } else { 
      $first_char = substr($line, 0, 1); 
      $type = self::LINE_TYPE_CONTEXT; 
      switch ($first_char) { 
       case self::MARKER_FILE_CHANGE: 
        $type = self::LINE_TYPE_CHANGE; 
        break; 
       case self::MARKER_FILE_LINE_NUMBERS: 
        $type = self::LINE_TYPE_LINE_NUMBERS; 
        break; 
       case self::MARKER_FILE_NORMAL_ADDITION: 
       case self::MARKER_FILE_UNIFIED_ADDITION: 
        $type = self::LINE_TYPE_ADDITION; 
        break; 
       case self::MARKER_FILE_NORMAL_DELETION: 
       case self::MARKER_FILE_UNIFIED_DELETION: 
        $type = self::LINE_TYPE_DELETION; 
        break; 
      } 
      $output[] = array($line, $type); 
     } 
     } 
     return $output; 
    } 
} 

有一個我剛剛發佈的輸出的JS小提琴here

讓我知道你在想什麼。它的邏輯非常簡單。

+0

謝謝你噸...你給了整個代碼:) – 2014-09-03 08:30:48

相關問題