#!/bin/python3
#
# Zusammenfassung der einzelnen Kapitel des Awk-Kurses zu einer HTML-Datei
#
# 11.12.2023

import re
import sys
import time
import cgi

sys.stdout = open('awk.html', 'w')

try:
    verbose = sys.argv[1].lower() == '-v'
except:
    verbose = 0

print('''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Die Programmiersprache AWK</title>
<style type="text/css">
.lh { line-height:2.5 }
.lh1 { line-height:1.2; font-weight:bold }
.lh2 { line-height:1.2 }
.comment { color:blue }
h4 { color:red }
.kw { font-weight:bold; font-family:monospace }
.kwb { font-weight:bold; font-family:monospace; color:blue }
</style>
</head>

<body>

<h1 style="text-align: center">Die Programmiersprache AWK</h1>

<hr />
<h2>Index</h2>

<ol class="lh">
''')

# Liste der einzufügenden Kapitel; die Reihenfolge ist relevant
kapitel = [
  'allg',
  'merkmale',
  'beispiele',
  'links',
]

# ein File (AWK-Quelltext) einlesen und in einer <pre>-Umgebung setzen; jede
# Zeile wird eingerückt und mit cgi.escape() kodiert; Kommentare werden der
# CSS-Klasse comment zugeordnet
def read_file(file_name):
    result = ['<pre class="lh1">']
    for line in open('CODE/' + file_name):
        line = '  ' + cgi.escape(line)
        if ' #' in line:
            # Leerzeichen gefolgt von Doppelkreuz vorhanden
            # das werten wir als Kommentar; diese primitive Implementierung ist nicht
            # allgemeingültig, reicht für uns aber aus
            line = re.sub(r'(?i)(#[^#]*)$', r'<span class="comment">\1</span>', line)
        # lange Strings, die in """ eingeschlossen sind, färben wir wie Kommentare
        result.append(line)

    result.append('</pre>')
    return ''.join(result)

# Include-Direktiven der Form #include(filename) auflösen
def include_files(line_list):
    for i in range(len(line_list)):
        line = line_list[i]
        m = re.search(r'(?i)#include\s*\(([^)]+)\)', line)
        if m:
            line_list[i] = line[:m.start()] + read_file(m.group(1)) + line[m.end():]
    return line_list

# Dictionary der Kapitel-Inhalte
inhalte = {}

# Index ausgeben

# alle Kapitel durchgehen
kap_nr = 0
for kap in kapitel:
    # Kapitel-Nummer hochzählen
    kap_nr += 1
    # Kapitel-Datei einlesen
    text = open('%s.html' % kap).readlines()
    # aus Zeile 1 die Überschrift und die Referenz darauf entnehmen
    m = re.search(r'(?is)^<h.><a name="?(.*?)"?\s*?>(.+?)</a>', text[0])
    ref = m.group(1)
    ueberschrift = m.group(2)
    # Inhalt merken; dann brauchen wir jedes File nur 1 Mal lesen;
    # wir fügen in die Überschrift noch die Kapitel-Nummer ein
    text[0] = re.sub(r'(?is)^<h.><a name="?.*?"?\s*?>', r'\g<0>%s. ' % kap_nr, text[0])
    inhalte[kap] = text
    # Index-Zeile ausgeben
    print('<li><a href="#%s">%s</a></li>' % (ref, ueberschrift))

# Ende Index
print('</ol>')

# Kapitel-Texte zu einem Gesamt-Text zusammenfügen
text_ges = ''
for kap in kapitel:
    text_ges += '<hr />\n\n' + ''.join(include_files(inhalte[kap]))
#open('text_ges.txt', 'w').write(text_ges)

# Anker-Namen suchen und zusammen mit den zugehörigen Texten in einem Dictionary
# ablegen
all_names = re.findall(r'(?is)<a\s+name="?(.*?)"?\s*?>(.*?)</a>', text_ges)
name_dict = {}
for name, text in all_names:
    if name in name_dict:
        print('Anker %s ist nicht eindeutig!' % name, file=sys.stderr)
    else:
        name_dict[name] = text
#open('name_dict.txt', 'w').write(`name_dict`)

# Bezugnahemen auf lokale Anker-Namen suchen und zusammen mit den zugehörigen
# Texten in einem Dictionary ablegen
all_refs = re.findall(r'(?is)<a\s+href="?#(.*?)"?\s*?>(.*?)</a>', text_ges)
ref_dict = {}
for name, text in all_refs:
    if verbose and name in ref_dict and ref_dict[name] != text:
        print('differierender Referenz-Text: %s: %s / %s' % (name, ref_dict[name], text), file=sys.stderr)
    else:
        ref_dict[name] = text
#open('ref_dict.txt', 'w').write(`ref_dict`)

# prüfen, ob Referenzen ins Leere gehen, und Texte von Bezugnahmen ggf.
# korrigieren
for name in ref_dict:
    if name not in name_dict:
        print('ungültige Referenz: %s / %s' % (name, ref_dict[name]), file=sys.stderr)
        continue
    if ref_dict[name] != name_dict[name]:
        # Abweichung der Texte melden
        if verbose:
            print('Korrektur?: %s: %s --> %s' % (name, ref_dict[name], name_dict[name]), file=sys.stderr)
        # Korrektur ggf. vornehmen
        #text_ges = re.sub(r'(?<=href=)("?#%s"?\s*?>)(.*?)(?=</a>)' % name, r'\1' + name_dict[name], text_ges)

# Gesamt-Text ausgeben
print(text_ges)

print('''
<hr />
<address>
<p><a href= "http://www.tu-chemnitz.de/urz/kontakt.html#mitarbeiter">Holger Trapp</a></p>
letzte Modifikation: %s
</address>

</body>
</html>''' % time.strftime('%d.%m.%Y', time.localtime(time.time())))
