Revision-History of the File rcshist.awk

1.17 Display diffs in gray boxes
--- rcshist.awk	2024/03/04 15:45:52	1.17 
+++ rcshist.awk	2024/03/04 16:15:50	1.18 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.17 2024/03/04 15:45:52 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.18 2024/03/04 16:15:50 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -123,6 +123,7 @@ 
     print "ins, del { text-decoration: none; }" 
     print "ins { color : darkgreen; }" 
     print "del { color : darkred; }" 
+    print "pre { background: #0001; border: 1px solid gray; padding: 8px; }" 
     print "</style>" 
 } 
  
1.16 Use correct date for <time>
--- rcshist.awk	2024/03/04 15:43:12	1.16 
+++ rcshist.awk	2024/03/04 15:45:52	1.17 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.16 2024/03/04 15:43:12 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.17 2024/03/04 15:45:52 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -39,7 +39,7 @@ 
     } 
 } 
  
-function diff(r1, r2, date) { 
+function diff(r1, r2) { 
     cmd = "rcsdiff -du -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
 	if (output ~ /^\-/) { 
@@ -67,7 +67,7 @@ 
     split(messages[rev - 1], lines, /\034/) 
     cmsg["class"] = "cmsg" 
     print "<summary>"				 
-    xml("time", fix_date(dates[rev_i]))	 
+    xml("time", fix_date(dates[rev - 1]))	 
     xml("a", revs[rev], link)		 
     xml("span", lines[1], cmsg)		 
     print "</summary>" 
@@ -76,7 +76,7 @@ 
     } 
  
     print "<pre>" 
-    diff(revs[rev], revs[rev - 1], dates[rev - 1]) 
+    diff(revs[rev], revs[rev - 1]) 
     print "</pre>" 
  
     print "</details>" 
1.15 Escape all rcsdiff output
--- rcshist.awk	2024/03/04 15:41:26	1.15 
+++ rcshist.awk	2024/03/04 15:43:12	1.16 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.15 2024/03/04 15:41:26 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.16 2024/03/04 15:43:12 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -47,7 +47,7 @@ 
 	} else if (output ~ /^\+/) { 
 	    xml("ins", output) 
 	} else { 
-	    printf("%s", output) 
+	    xml("code", output) 
 	} 
 	printf("\n") 
     } 
1.14 Generate diffs in the "unified" format
--- rcshist.awk	2024/02/28 10:56:09	1.14 
+++ rcshist.awk	2024/03/04 15:41:26	1.15 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.14 2024/02/28 10:56:09 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.15 2024/03/04 15:41:26 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -40,11 +40,11 @@ 
 } 
  
 function diff(r1, r2, date) { 
-    cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
+    cmd = "rcsdiff -du -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
-	if (output ~ /^</) { 
+	if (output ~ /^\-/) { 
 	    xml("del", output) 
-	} else if (output ~ /^>/) { 
+	} else if (output ~ /^\+/) { 
 	    xml("ins", output) 
 	} else { 
 	    printf("%s", output) 
1.13 Allow specifying a stylesheet
--- rcshist.awk	2024/02/25 18:23:57	1.13 
+++ rcshist.awk	2024/02/28 10:56:09	1.14 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.13 2024/02/25 18:23:57 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.14 2024/02/28 10:56:09 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -12,6 +12,9 @@ 
 #  
 #	$ rlog FILE | awk -f rcshist.awk 
 # 
+# Optionally pass a "-v CSS=[some url here]" flag to awk if you want 
+# to use a specific stylesheet. 
+# 
 # This script is a fork of Florian's non-POSIX/Kernighan compliant 
 # version https://wwwcip.cs.fau.de/~oc45ujef/misc/src/rcshist.awk. 
  
@@ -113,6 +116,7 @@ 
     print "<head>" 
     print "<meta charset=\"utf-8\">" 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
+    if (CSS) { print "<link href=\"" CSS "\" rel=\"stylesheet\">" } 
     print "<style>" 
     print ":target .cmsg { font-weight: bold; }" 
     print "time { float: right; }" 
1.12 Make adjustments according to https://validator.w3.org/
--- rcshist.awk	2024/02/25 18:18:16	1.12 
+++ rcshist.awk	2024/02/25 18:23:57	1.13 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.12 2024/02/25 18:18:16 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.13 2024/02/25 18:23:57 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -109,9 +109,9 @@ 
  
 BEGIN { 
     print "<!DOCTYPE html>" 
-    print "<html>" 
+    print "<html lang=\"en\">" 
     print "<head>" 
-    print "<meta charset=\"utf-8\" />" 
+    print "<meta charset=\"utf-8\">" 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "<style>" 
     print ":target .cmsg { font-weight: bold; }" 
@@ -123,7 +123,7 @@ 
 } 
  
 END { 
-    print "<hr/>" 
+    print "<hr>" 
     print "<footer>Impartially generated by a <a href=\"https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk\">fork</a> of <a href=https://wwwcip.cs.fau.de/~oc45ujef/misc/src/rcshist.awk>rcshist.awk</a></footer>" 
  
     # pretty disgusting, I have to say 
1.11 Reorder functions by occurrence
--- rcshist.awk	2024/02/25 18:17:26	1.11 
+++ rcshist.awk	2024/02/25 18:18:16	1.12 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.11 2024/02/25 18:17:26 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.12 2024/02/25 18:18:16 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -17,21 +17,6 @@ 
  
 ### Code 
  
-function diff(r1, r2, date) { 
-    cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
-    while ((cmd | getline output) > 0){ 
-	if (output ~ /^</) { 
-	    xml("del", output) 
-	} else if (output ~ /^>/) { 
-	    xml("ins", output) 
-	} else { 
-	    printf("%s", output) 
-	} 
-	printf("\n") 
-    } 
-    close(cmd) 
-} 
- 
 function xml(tag, content, attr) { 
     printf("<%s", tag) 
     for (key in attr) { 
@@ -51,6 +36,27 @@ 
     } 
 } 
  
+function diff(r1, r2, date) { 
+    cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
+    while ((cmd | getline output) > 0){ 
+	if (output ~ /^</) { 
+	    xml("del", output) 
+	} else if (output ~ /^>/) { 
+	    xml("ins", output) 
+	} else { 
+	    printf("%s", output) 
+	} 
+	printf("\n") 
+    } 
+    close(cmd) 
+} 
+ 
+function fix_date(date) { 
+    split("", date_parts) 
+    split(date, date_parts, "/") 
+    return date_parts[1] "-" date_parts[2] "-" date_parts[3] 
+} 
+ 
 function diff_to_html(rev) { 
     printf("<details id='%s'>", "rev" revs[rev]) 
  
@@ -73,12 +79,6 @@ 
     print "</details>" 
 } 
  
-function fix_date(date) { 
-    split("", date_parts) 
-    split(date, date_parts, "/") 
-    return date_parts[1] "-" date_parts[2] "-" date_parts[3] 
-} 
- 
 /^Working file/ { 
     file = $3 
     xml("title", "Revision-History of the File " file) 
1.10 Have "xml" generate output directly after all
--- rcshist.awk	2024/02/25 18:11:22	1.10 
+++ rcshist.awk	2024/02/25 18:17:26	1.11 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.10 2024/02/25 18:11:22 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.11 2024/02/25 18:17:26 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -21,41 +21,34 @@ 
     cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
 	if (output ~ /^</) { 
-	    printf("%s\n", xml("del", output)) 
+	    xml("del", output) 
 	} else if (output ~ /^>/) { 
-	    printf("%s\n", xml("ins", output)) 
+	    xml("ins", output) 
 	} else { 
-	    printf("%s\n", output) 
+	    printf("%s", output) 
 	} 
+	printf("\n") 
     } 
     close(cmd) 
 } 
  
 function xml(tag, content, attr) { 
-    str = "<" tag 
- 
-    for (key in attr) 
-	str = str " " key "=\"" attr[key] "\"" 
+    printf("<%s", tag) 
+    for (key in attr) { 
+	printf(" %s=\"%s\"", key, attr[key]) 
+    } 
  
-    if (!content) str = str " />" 
+    if (!content) printf("/> ") 
     else { 
-	if (content ~ /^</) { 
-	    str = str ">\n" 
-	} else { 
-	    str = str ">" 
- 
 	    # https://www.w3.org/TR/xml/#dt-escape 
 	    gsub(/&/, "\\&amp;", content) 
 	    gsub(/>/, "\\&gt;", content) 
 	    gsub(/</, "\\&lt;", content) 
 	    gsub(/'/, "\\&apos;", content) 
 	    gsub(/"/, "\\&quot;", content) 
-	} 
  
-	str = str content "</" tag ">" 
+	printf(">%s</%s> ", content, tag) 
     } 
- 
-    return str " " 
 } 
  
 function diff_to_html(rev) { 
@@ -64,13 +57,13 @@ 
     link["href"] = "#rev" revs[rev] 
     split(messages[rev - 1], lines, /\034/) 
     cmsg["class"] = "cmsg" 
-    print "<summary>"				\ 
-	xml("time", fix_date(dates[rev_i]))	\ 
-	xml("a", revs[rev], link)		\ 
-	xml("span", lines[1], cmsg)		\ 
-	"</summary>" 
+    print "<summary>"				 
+    xml("time", fix_date(dates[rev_i]))	 
+    xml("a", revs[rev], link)		 
+    xml("span", lines[1], cmsg)		 
+    print "</summary>" 
     if (length(lines[2]) > 1) { 
-	print xml("p", lines[2]) 
+	 xml("p", lines[2]) 
     } 
  
     print "<pre>" 
@@ -88,10 +81,10 @@ 
  
 /^Working file/ { 
     file = $3 
-    print xml("title", "Revision-History of the File " file) 
+    xml("title", "Revision-History of the File " file) 
     print "</head>" 
     print "<body>" 
-    print xml("h1", "Revision-History of the File " file) 
+    xml("h1", "Revision-History of the File " file) 
     rev_i = 0 
 } 
  
1.9 Remove unnecessary visual styling
--- rcshist.awk	2024/02/25 18:10:05	1.9 
+++ rcshist.awk	2024/02/25 18:11:22	1.10 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.9 2024/02/25 18:10:05 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.10 2024/02/25 18:11:22 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -122,12 +122,10 @@ 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "<style>" 
     print ":target .cmsg { font-weight: bold; }" 
-    print "details { padding: 4px; }" 
     print "time { float: right; }" 
     print "ins, del { text-decoration: none; }" 
     print "ins { color : darkgreen; }" 
     print "del { color : darkred; }" 
-    print "pre { padding: 4px; background: whitesmoke; }" 
     print "</style>" 
 } 
  
1.8 Escape > using &gt;, not &lt;
--- rcshist.awk	2024/02/25 18:09:44	1.8 
+++ rcshist.awk	2024/02/25 18:10:05	1.9 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.8 2024/02/25 18:09:44 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.9 2024/02/25 18:10:05 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -46,7 +46,7 @@ 
  
 	    # https://www.w3.org/TR/xml/#dt-escape 
 	    gsub(/&/, "\\&amp;", content) 
-	    gsub(/>/, "\\&lt;", content) 
+	    gsub(/>/, "\\&gt;", content) 
 	    gsub(/</, "\\&lt;", content) 
 	    gsub(/'/, "\\&apos;", content) 
 	    gsub(/"/, "\\&quot;", content) 
1.7 Fix formatting of diffs in <pre> blocks
--- rcshist.awk	2024/02/25 18:03:43	1.7 
+++ rcshist.awk	2024/02/25 18:09:44	1.8 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.7 2024/02/25 18:03:43 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.8 2024/02/25 18:09:44 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -21,11 +21,11 @@ 
     cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
 	if (output ~ /^</) { 
-	    print xml("del", output) 
+	    printf("%s\n", xml("del", output)) 
 	} else if (output ~ /^>/) { 
-	    print xml("ins", output) 
+	    printf("%s\n", xml("ins", output)) 
 	} else { 
-	    print output 
+	    printf("%s\n", output) 
 	} 
     } 
     close(cmd) 
@@ -55,7 +55,7 @@ 
 	str = str content "</" tag ">" 
     } 
  
-    return str "\n" 
+    return str " " 
 } 
  
 function diff_to_html(rev) { 
1.6 Inject some basic styling in <head>
--- rcshist.awk	2024/02/25 17:59:28	1.6 
+++ rcshist.awk	2024/02/25 18:03:43	1.7 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.6 2024/02/25 17:59:28 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.7 2024/02/25 18:03:43 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -89,7 +89,6 @@ 
 /^Working file/ { 
     file = $3 
     print xml("title", "Revision-History of the File " file) 
-    print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "</head>" 
     print "<body>" 
     print xml("h1", "Revision-History of the File " file) 
@@ -119,6 +118,17 @@ 
     print "<!DOCTYPE html>" 
     print "<html>" 
     print "<head>" 
+    print "<meta charset=\"utf-8\" />" 
+    print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
+    print "<style>" 
+    print ":target .cmsg { font-weight: bold; }" 
+    print "details { padding: 4px; }" 
+    print "time { float: right; }" 
+    print "ins, del { text-decoration: none; }" 
+    print "ins { color : darkgreen; }" 
+    print "del { color : darkred; }" 
+    print "pre { padding: 4px; background: whitesmoke; }" 
+    print "</style>" 
 } 
  
 END { 
1.5 Actually print the output of "xml"
--- rcshist.awk	2024/02/25 17:56:04	1.5 
+++ rcshist.awk	2024/02/25 17:59:28	1.6 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.5 2024/02/25 17:56:04 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.6 2024/02/25 17:59:28 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -61,17 +61,14 @@ 
 function diff_to_html(rev) { 
     printf("<details id='%s'>", "rev" revs[rev]) 
  
-    print "<summary>" 
-    xml("time", fix_date(dates[rev_i])) 
- 
     link["href"] = "#rev" revs[rev] 
-    xml("a", revs[rev], link) 
- 
     split(messages[rev - 1], lines, /\034/) 
     cmsg["class"] = "cmsg" 
-    xml("span", lines[1], cmsg) 
-    print "</summary>" 
- 
+    print "<summary>"				\ 
+	xml("time", fix_date(dates[rev_i]))	\ 
+	xml("a", revs[rev], link)		\ 
+	xml("span", lines[1], cmsg)		\ 
+	"</summary>" 
     if (length(lines[2]) > 1) { 
 	print xml("p", lines[2]) 
     } 
@@ -91,11 +88,11 @@ 
  
 /^Working file/ { 
     file = $3 
-    xml("title", "Revision-History of the File " file) 
+    print xml("title", "Revision-History of the File " file) 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "</head>" 
     print "<body>" 
-    xml("h1", "Revision-History of the File " file) 
+    print xml("h1", "Revision-History of the File " file) 
     rev_i = 0 
 } 
  
1.4 Inject newlines in between commit message lines
--- rcshist.awk	2024/02/25 17:54:45	1.4 
+++ rcshist.awk	2024/02/25 17:56:04	1.5 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.4 2024/02/25 17:54:45 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.5 2024/02/25 17:56:04 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -106,7 +106,7 @@ 
     sub(/^Summary: */, "", message) 
     message = message "\034" 
     while ((getline line) > 0 && !(line ~ /^-+$/)) { 
-        message = message line 
+        message = message "\n" line 
     } 
  
     messages[rev_i] = message 
1.3 Use my "xml" function
--- rcshist.awk	2024/02/25 17:16:43	1.3 
+++ rcshist.awk	2024/02/25 17:54:45	1.4 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.3 2024/02/25 17:16:43 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.4 2024/02/25 17:54:45 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -21,9 +21,9 @@ 
     cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
 	if (output ~ /^</) { 
-            print "<del>" html_escape(output) "</del>" 
+	    print xml("del", output) 
 	} else if (output ~ /^>/) { 
-            print "<ins>" html_escape(output) "</ins>" 
+	    print xml("ins", output) 
 	} else { 
 	    print output 
 	} 
@@ -31,35 +31,55 @@ 
     close(cmd) 
 } 
  
-function html_escape(string) { 
-    gsub(/&/, "\\&amp;", string) 
-    gsub(/</, "\\&lt;", string) 
-    gsub(/>/, "\\&gt;", string) 
-    gsub(/"/, "\\&quot;", string) 
-    return string 
-} 
+function xml(tag, content, attr) { 
+    str = "<" tag 
  
-function tag(tag, body) { 
-    print "<" tag ">" html_escape(body) "</" tag ">" 
+    for (key in attr) 
+	str = str " " key "=\"" attr[key] "\"" 
+ 
+    if (!content) str = str " />" 
+    else { 
+	if (content ~ /^</) { 
+	    str = str ">\n" 
+	} else { 
+	    str = str ">" 
+ 
+	    # https://www.w3.org/TR/xml/#dt-escape 
+	    gsub(/&/, "\\&amp;", content) 
+	    gsub(/>/, "\\&lt;", content) 
+	    gsub(/</, "\\&lt;", content) 
+	    gsub(/'/, "\\&apos;", content) 
+	    gsub(/"/, "\\&quot;", content) 
+	} 
+ 
+	str = str content "</" tag ">" 
+    } 
+ 
+    return str "\n" 
 } 
  
 function diff_to_html(rev) { 
+    printf("<details id='%s'>", "rev" revs[rev]) 
+ 
+    print "<summary>" 
+    xml("time", fix_date(dates[rev_i])) 
+ 
+    link["href"] = "#rev" revs[rev] 
+    xml("a", revs[rev], link) 
+ 
     split(messages[rev - 1], lines, /\034/) 
-    printf("<details id='%s'><summary>", "rev" revs[rev]) 
-    tag("time", fix_date(dates[rev_i])) 
-    printf("<a href='#%s'>%s</a>: <span class='cmsg'>%s</span>", 
-           "rev" revs[rev], revs[rev], html_escape(lines[1])) 
+    cmsg["class"] = "cmsg" 
+    xml("span", lines[1], cmsg) 
     print "</summary>" 
-    if (length(lines) > 1) { 
-        print "<p>" 
-        for (i = 2; i <= length(lines); i++) { 
-            print lines[i] 
-        } 
-        print "</p>" 
+ 
+    if (length(lines[2]) > 1) { 
+	print xml("p", lines[2]) 
     } 
+ 
     print "<pre>" 
     diff(revs[rev], revs[rev - 1], dates[rev - 1]) 
     print "</pre>" 
+ 
     print "</details>" 
 } 
  
@@ -71,13 +91,11 @@ 
  
 /^Working file/ { 
     file = $3 
-    print "<html>" 
-    print "<head>" 
-    tag("title", "Revision-History of the File " file) 
+    xml("title", "Revision-History of the File " file) 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "</head>" 
     print "<body>" 
-    tag("h1", "Revision-History of the File " file) 
+    xml("h1", "Revision-History of the File " file) 
     rev_i = 0 
 } 
  
@@ -86,9 +104,9 @@ 
     getline metadata 
     getline message 
     sub(/^Summary: */, "", message) 
-    message = html_escape(message) 
+    message = message "\034" 
     while ((getline line) > 0 && !(line ~ /^-+$/)) { 
-        message = message "\034" html_escape(line) 
+        message = message line 
     } 
  
     messages[rev_i] = message 
@@ -100,6 +118,12 @@ 
     } 
 } 
  
+BEGIN { 
+    print "<!DOCTYPE html>" 
+    print "<html>" 
+    print "<head>" 
+} 
+ 
 END { 
     print "<hr/>" 
     print "<footer>Impartially generated by a <a href=\"https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk\">fork</a> of <a href=https://wwwcip.cs.fau.de/~oc45ujef/misc/src/rcshist.awk>rcshist.awk</a></footer>" 
1.2 Write diff directly to standard output
--- rcshist.awk	2024/02/25 17:10:21	1.2 
+++ rcshist.awk	2024/02/25 17:16:43	1.3 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.2 2024/02/25 17:10:21 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.3 2024/02/25 17:16:43 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -17,19 +17,18 @@ 
  
 ### Code 
  
-function diff(r1, r2, file, date) { 
-    buffer = "" 
+function diff(r1, r2, date) { 
     cmd = "rcsdiff -b -r" r1 " -r" r2 " " file 
     while ((cmd | getline output) > 0){ 
 	if (output ~ /^</) { 
-            output = "<del>" html_escape(output) "</del>" 
+            print "<del>" html_escape(output) "</del>" 
 	} else if (output ~ /^>/) { 
-            output = "<ins>" html_escape(output) "</ins>" 
+            print "<ins>" html_escape(output) "</ins>" 
+	} else { 
+	    print output 
 	} 
-        buffer = buffer output "\n" 
     } 
     close(cmd) 
-    return buffer 
 } 
  
 function html_escape(string) { 
@@ -40,16 +39,16 @@ 
     return string 
 } 
  
-function gen_tag(tag, body) { 
+function tag(tag, body) { 
     print "<" tag ">" html_escape(body) "</" tag ">" 
 } 
  
-function diff_to_html(rev, message, date, dif) { 
-    split(message, lines, /\034/) 
-    printf("<details id='%s'><summary>", "rev" rev) 
-    gen_tag("time", fix_date(date)) 
+function diff_to_html(rev) { 
+    split(messages[rev - 1], lines, /\034/) 
+    printf("<details id='%s'><summary>", "rev" revs[rev]) 
+    tag("time", fix_date(dates[rev_i])) 
     printf("<a href='#%s'>%s</a>: <span class='cmsg'>%s</span>", 
-           "rev" rev, rev, html_escape(lines[1])) 
+           "rev" revs[rev], revs[rev], html_escape(lines[1])) 
     print "</summary>" 
     if (length(lines) > 1) { 
         print "<p>" 
@@ -58,7 +57,9 @@ 
         } 
         print "</p>" 
     } 
-    print "<pre>" dif "</pre>" 
+    print "<pre>" 
+    diff(revs[rev], revs[rev - 1], dates[rev - 1]) 
+    print "</pre>" 
     print "</details>" 
 } 
  
@@ -72,11 +73,11 @@ 
     file = $3 
     print "<html>" 
     print "<head>" 
-    gen_tag("title", "Revision-History of the File " file) 
+    tag("title", "Revision-History of the File " file) 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
     print "</head>" 
     print "<body>" 
-    gen_tag("h1", "Revision-History of the File " file) 
+    tag("h1", "Revision-History of the File " file) 
     rev_i = 0 
 } 
  
@@ -92,11 +93,10 @@ 
  
     messages[rev_i] = message 
     split(metadata, a, " ") 
-    date[rev_i] = a[2] " " a[3] 
-    sub(/;$/, "", date[rev_i]) 
-    if(rev_i > 1){ 
-        d = diff(revs[rev_i], revs[rev_i - 1], file, date[rev_i - 1]) 
-        diff_to_html(revs[rev_i], messages[rev_i - 1], date[rev_i - 1],d) 
+    dates[rev_i] = a[2] " " a[3] 
+    sub(/;$/, "", dates[rev_i]) 
+    if (rev_i > 1) { 
+        diff_to_html(rev_i) 
     } 
 } 
  
1.1 Remove reference to custom stylesheet
--- rcshist.awk	2024/02/25 17:08:56	1.1 
+++ rcshist.awk	2024/02/25 17:10:21	1.2 
@@ -2,7 +2,7 @@ 
  
 # Author: Florian Guthmann <florian.guthmann@fau.de> 
 # Maintainer: Philip Kaludercic <philip.kaludercic@fau.de> 
-# Version: $Id: rcshist.awk,v 1.1 2024/02/25 17:08:56 oj14ozun Exp $ 
+# Version: $Id: rcshist.awk,v 1.2 2024/02/25 17:10:21 oj14ozun Exp $ 
 # URL: https://wwwcip.cs.fau.de/~oj14ozun/src+etc/rcshist.awk 
  
 ### Commentary 
@@ -74,7 +74,6 @@ 
     print "<head>" 
     gen_tag("title", "Revision-History of the File " file) 
     print "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">" 
-    print "<link rel=stylesheet href=./alt.css type=text/css>" 
     print "</head>" 
     print "<body>" 
     gen_tag("h1", "Revision-History of the File " file)