• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Per Script (sed,bash,perl...???) Endnoten zu Fußnoten

A

Anonymous

Gast
Hallo liebe Leute,

ich habe mir mal wieder ein kompliziertes Unterfangen aufgebürdet ...
Ich habe mehrere Internetdokumente (HTML), die ich nach LaTeX umformatieren möchte -- die meisten Sachen sind ja nicht so schwierig (ist ja ähnliche "Sprache"), jedoch beiße ich mir an einer Sache die Zähne aus.
Ich möchte die im HTML-Dokument exisiterenden Endnoten in Fußnoten umformatieren.
Eine Beispiel-HTML-Datei sieht ungefäht so aus:
Code:
[...]
<p>bla blub bla bla (1), bli bla blub</p>
[...]
<p><b>Anmerkungen</b>: </p>
<p>(1) Vgl. bla bla bla, seite eins. </p>
[...]
Und so soll es etwa aussehen:
Code:
bla blub bla bla \footnote{Vgl. bla bla bla, seite eins.}, bli bla blub

Man müsste also die Endnote nach oben an die richtige Stelle kopieren.
So Pseudocode-mäßig:
gehe durch den Text; wenn du "( + beliebige Zahlen" findest, dann merke dir die Zahl, suche weiter; wenn du diese Zeichenkette wiederfindest, dann schneide den Text aus, der innerhalb desselben Absatzes (<p>) ist und füge ihn wieder oben ein.

Ich habe mich schon durch alle möglichen sed, awk und sonstigen Sachen gequält, komme aber einfach nicht weiter.
Mit speziellen Script-/Programmiersprachen habe ich nicht so wirklich Erfahrung, aber wenn es nicht allzu viel Aufwand ist, würde ich mich sogar ein bisschen Perl o.ä. lernen.
Weiß einer von euch Rat?

[edit]ich hatte auch schon vor, es händisch zu machen -- aber es sind tausende ...[/edit]

MfG. Mercedesdriver :)
 
Hmmm, nicht ganz so einfach. Klar könntest Du das mit einem Funktionsaufruf machen wenn {Klammerauf digit Klammerzu} nicht direkt nach <p> gefunden wird, aber dazu fehlt die Info: Kannst Du sicherstellen das diese Bedingung immer nur auf einer Zeile steht? Zweitens: Wie soll in den Kommentaren mit den sicherlich vorhandenen Sonderzeichen (ala <br>) und/oder Zeilenumbrüchen umgegangen werden? Wenn Du das für dich selbst klären kannst, ist die Umsetzung in Perl oder andere Skriptsprachen kein Problem.
 

framp

Moderator
Teammitglied
Wenn Du Text, der später entdeckt wird, vorher in ein Doc einfügen willst ist das mit sed und awk nicht möglich. Du musst da schon perl oder python benutzen. bash würde auch gehen ... aber umständlicher.
 
OP
A

Anonymous

Gast
Hmm ich muss zugeben ich konnte euch nicht ganz folgen (mag an der späten Stunde liegen).
Also anscheinend geht es nur mit einer Scriptsprache (bash/perl/python ...).
Jetzt muss ich zugeben, dass ich mich damit (abgesehen von bash) noch überhaupt nicht auskenne -- habt ihr vielleicht Beispiele, wie ich vorgehen könnte?

MfG. Mercedesdriver :)
 

abgdf

Guru
Es gibt ein paar allgemeine Lösungen für html -> LaTeX:

http://html2latex.sourceforge.net/
http://www.iwriteiam.nl/html2tex.html

Bei ersterem könnte Dir das zusätzliche Installieren der erforderlichen Perl-Module möglicherweise schwerfallen, wenn Du damit nicht so viel Erfahrungen hast. Kann aber auch sein, daß die Module schon bei der Linux-Distribution mit dabei sind, z.B. als rpm.
Generell sind Fußnoten in einer html-Seite auch eher ungewöhnlich, so daß ich bezweifle, daß die allgemeinen Programme was damit anfangen können.

Ansonsten hab' ich sowas Ähnliches schon häufiger geschrieben (meist in Python). Das waren aber immer Speziallösungen, das heißt, dafür muß man den genauen Input kennen. Je nachdem, wie man das Dokument umwandeln will, kann so ein Skript auch 100-200 Zeilen lang werden.
Im Grunde muß man beim Durchgehen der Zeilen ein Flag in dem Bereich setzen, der einen interessiert. Dann kann man sich daraus die Fußnoten greifen und weiterverarbeiten:
Beispiel (Python 2.x):
Code:
#!/usr/bin/python
# coding: iso-8859-1

text = """[...]
<p>bla blub bla bla (1), bli bla blub</p>
[...]
<p><b>Anmerkungen</b>: </p>
<p>(1) Vgl. bla bla bla, seite eins. </p>
[...]"""

text = text.split("\n")

fn = False
for i in text:
    if fn:
        print "Fußnote: " + i
    i = i.rstrip("\n")
    if i == "<p><b>Anmerkungen</b>: </p>":
        fn = True
 
OP
A

Anonymous

Gast
@abgdf: Vielen Dank für die Information -- bei meinem Fall wird es sich wohl tatsächlich eher um eine Speziallösung handeln.
Die konkrete HTML-Datei wäre bei mir http://www.vatican.va/archive/hist_councils/ii_vatican_council/documents/vat-ii_const_19641121_lumen-gentium_ge.html -- aber wie gesagt, das wäre auch nur ein Beispiel / ein Anfang.
Wie schon erwähnt, sind zudem in der HTML-Datei keine Fußnoten in dem Sinne, sondern halt nur im Text z.B. eine "(1)", und am Ende der Seite ist dann unter "(1) " die entsprechende Fußnote/Literaturangabe/Bemerkung zu finden.
Ich habe leider überhaupt keine Ahnung wie ich anfangen könnte -- wüsstest du ein Beispiel, was zu meinem Fall passen würde?

MfG. Mercedesdriver :)
 

framp

Moderator
Teammitglied
abgdf schrieb:
Es gibt ein paar allgemeine Lösungen für html -> LaTeX:

http://html2latex.sourceforge.net/
http://www.iwriteiam.nl/html2tex.html
Dachte ich mir schon. Es muss ja nicht immer wieder ein xslt für htlm -> latex neu geschrieben werden. Man muss nun wirklich nicht immer wieder das Rad neu erfinden.
 

abgdf

Guru
mercedesdriver schrieb:
Die konkrete HTML-Datei wäre bei mir http://www.vatican.va/archive/hist_councils/ii_vatican_council/documents/vat-ii_const_19641121_lumen-gentium_ge.html
Hmm, vielleicht könnte ich dort die Fußnoten "greifen". Die Frage wäre dann aber, wo Du sie hinhaben willst. Weiß ja nicht, wie Dein LaTeX-Dokument aussieht.

Mal 'ne andere Frage: Die Vatikanseite sieht so aus, als hätten die da ganz fähige Webdesigner. Wenn Du dorthin Kontakte hast, könnten ja vielleicht die die Umwandlung vornehmen?
Kann mir eigentlich eigentlich nicht vorstellen, daß sie das Dokument und die Fußnoten nur als html haben sollten.

Erinnert mich irgendwie alles ein bißchen an die Miniaturenmaler bei "Der Name der Rose". :D

Gruß

P.S.: Da mich ja auch das Thema Skriptsprachen und Texte interessiert, war ich mal auf eine Seite gestoßen, die in diesem Zusammenhang (zu meinem Erstaunen) aus dem Bereich der Kirche kam, das war diese. Und offenbar gibt es da sogar eine besondere Community:

http://luki.org

Vielleicht könnte man Dir auch da helfen.
 
OP
A

Anonymous

Gast
@abgdf: Schon einmal vielen Dank für die weiteren Hinweise und Beispiele.
Zunächst zur anderen Frage: Ja die haben tatsächlich fähige Leute (soweit ich informiert bin) -- aber ich hatte bisher keinen Kontakt zu denen (kann ja noch werden, ist aber denke ich nicht ganz leicht). Außerdem kann ich ja sonst nichts dabei lernen :) .
Also eigentlich bräuchte ich ja nur die Anmerkungen unten [z.B.: (1) Vgl. Cyprian, Epist. ...] nach oben kopiert haben, wo die (1) das erste Mal auftaucht. Am Ende würde da z.B. stehen:
Code:
vorher:
[...]wurde sie auf wunderbare Weise vorbereitet (1), in den letzten Zeiten gestiftet,[...]
nachher:
[...]wurde sie auf wunderbare Weise vorbereitet\footnote{(1) Vgl. Cyprian, Epist. 64, 4: PL 3, 1017; CSEL (Hartel), III B, 720. Hilarius v. Poitiers, In Mt. 23,6: PL 9, 1047. Augustinus, passim. Cyrill v. Alex., Glaph. in Gen. 2,10: PG 69, 110 A.}, in den letzten Zeiten gestiftet,[...]
Die anderen Formatierungen bekomme ich glaube ich auch so hin / muss ich wohl von Hand machen (eine ordentliche Überschriftenstruktur bietet das HTMLK-Dokument ja nicht).

Ich hab schon überlegt, ob man sozusagen die Anmerkungen in ein Array(?) einlesen könnte und dann einfach nach Zahl an der passenden Stelle den Text einfügen könnte. Aber wie gesagt, ich habe keine Ahnung.

Für heute zunächst eine gute Nacht
MfG. Mercedesdriver :)

PS: LuKi kenne ich natürlich ;) -- evtl. wollte ich sogar mal irgendwann was Schlaues über Informationsethik + Libre Software schrieben ... mal sehen
 

abgdf

Guru
Also, folgendes sollte mit der html-Datei

http://www.vatican.va/archive/hist_councils/ii_vatican_council/documents/vat-ii_const_19641121_lumen-gentium_ge.html

klappen, aber wahrscheinlich mit keiner anderen Deiner Dateien:
Code:
#!/usr/bin/env python
# coding: iso-8859-1

import os

INPUTFILE  = "vat-ii_const_19641121_lumen-gentium_ge.html"
OUTPUTFILE = "out.txt"

def changeLine(l):
    l = l.rstrip("\n")
    l = l.replace(""", '"')
    l = l.replace("<i>", "")
    l = l.replace("</i>", "")
    l = l.replace("<b>", "")
    l = l.replace("</b>", "")
    l = l.replace("<p>", "")
    l = l.replace("</p>", "")
    l = l.replace("</i>", "")
    l = l.rstrip(" ")
    return l

fh = file(os.path.join(os.getcwd(), INPUTFILE), "r")
a = fh.readlines()
fh.close()

fn = False
b = []
for i in a:
    i = changeLine(i)
    if i == "Anmerkungen:":
        fn = True
        continue
    if i == '<P align="left">     </P>':
        fn = False
    if fn:
        b.append(i)

c = []
x = 0
fnindex = 1
cind = 0
while x < len(b):
    if b[x].startswith("(" + str(fnindex) + ")"):
        c.append(b[x])
        x += 1
        fnindex += 1
        while x < len(b) and not b[x].startswith("(" + str(fnindex) + ")"):
            c[cind] += b[x]
            x += 1
        cind += 1
        continue
    x += 1

for i in range(len(c)):
    d = c[i].split(") ")
    c[i] = ") ".join(d[1:])

fh2 = file(os.path.join(os.getcwd(), OUTPUTFILE), "w")
for i in c:
    fh2.write("\\footnote{" + i + "}\n")
fh2.close()
Die html-Datei muß in demselben Verzeichnis wie das Pythonskript sein. Der Output erfolgt in eine Datei "out.txt", ebenfalls in diesem Verzeichnis.
Ok so?
 
OP
A

Anonymous

Gast
Vielen Dank schonmal abgdf!
Ich hatte zunächst ein paar Probleme micht der Python-Version -- bei mit scheint der Code nur unter Python2 zu laufen.
Bei Python3 kommt folgende Fehlermeldung:
Code:
Traceback (most recent call last):
  File "./konverter.py", line 22, in <module>
    fh = file(os.path.join(os.getcwd(), INPUTFILE), "r")
NameError: name 'file' is not defined
Jetzt sind ja die Fußnoten schön entsprechend umgesetzt -- jetzt nur noch das entscheidende:
Die Fußnoten müssten im Text an die entsprechende Stelle eingesetzt werden -- also aus der entstandenen out.txt die erste Zeile statt die (1) im Text. Wie ginge das denn?


PS: Verwendest du eine Entwicklungsumgebung? Ich hab mal eric5 ausprobiert ...
 

abgdf

Guru
mercedesdriver schrieb:
Vielen Dank schonmal abgdf!
Ich hatte zunächst ein paar Probleme micht der Python-Version -- bei mit scheint der Code nur unter Python2 zu laufen.
Bei Python3 kommt folgende Fehlermeldung:
Code:
Traceback (most recent call last):
  File "./konverter.py", line 22, in <module>
    fh = file(os.path.join(os.getcwd(), INPUTFILE), "r")
NameError: name 'file' is not defined
Ah ja. Zum Öffnen einer Datei verwendet man in vielen Sprache "open()", z.B. in Perl, siehe "perldoc -f open". Python hatte irgendwann stattdessen "file()" eingeführt, das aber dasselbe macht, also nur ein anderes Schlüsselwort dafür. In Python 3.x heißt es nun wieder "open()". Im Grunde nur eine Mode.
Aber diese Versionsinkompatibilitäten sind schon ein bißchen ärgerlich. Es gibt sogar ein Konverterskript dafür. Viele - wie ich - bleiben lieber bei Python 2.x.
mercedesdriver schrieb:
Jetzt sind ja die Fußnoten schön entsprechend umgesetzt
Ah, das klingt schonmal gut. Ich sehe gerade noch das Problem, daß mein Skript manchmal ein Leerzeichen zuviel entfernt hat, z.B. bei "imRömischen Brevier". Ein Problem war, daß in der html-Datei die Fußnoten über mehrere Zeilen gingen. Die mußte ich irgendwie zu einer Zeile zusammenbringen. Manche Zeilen hatten am Ende Leerzeichen, die da nicht hingehörten und daher zuvor entfernt worden waren. Wenn jetzt die nächste Zeile hinzugefügt wurde, entstand dieser Fehler. Für mich zur Zeit schwer zu beheben.
Ein anderes Problem war, daß es Jahreszahlenangaben wie "(1853)" gab. Diese mußten von den Fußnoten wie "(25)" unterschieden werden.
Es gab da insgesamt gar nicht wenige Probleme.
mercedesdriver schrieb:
-- jetzt nur noch das entscheidende:
Die Fußnoten müssten im Text an die entsprechende Stelle eingesetzt werden -- also aus der entstandenen out.txt die erste Zeile statt die (1) im Text. Wie ginge das denn?
Dazu nochmal folgendes Skript:
Code:
#!/usr/bin/env python
# coding: iso-8859-1

import os

LATEXINPUT = "latextext.txt"
FNINPUT = "out.txt"
OUTPUT = "out2.txt"

def getFile(fname):
    fh = open(os.path.join(os.getcwd(), fname), "r")
    a = fh.readlines()
    fh.close()
    for i in range(len(a)):
        a[i] = a[i].rstrip("\n")
    return a

a = getFile(LATEXINPUT)
b = getFile(FNINPUT)

fh2 = open(os.path.join(os.getcwd(), OUTPUT), "w")
ind = 1
from_ = "(" + str(ind) + ")"
x = 0
to_ = b[x]
for i in a:
    while from_ in i:
        i = i.replace(from_, to_, 1)
        ind += 1
        from_ = "(" + str(ind) + ")"
        x += 1
        to_ = b[x]
    fh2.write(i + "\n")
fh2.close()
Es liest die Fußnoten aus der Datei "out.txt" (s.o.) und Deinen Latex-Text aus einer Datei "latextext.txt" (alles wie oben im selben Verzeichnis wie das Skript"). Der Output erfolgt nach "out2.txt".
Auch das ist etwas brüchig: Dein Latex-Text muß exakt 195 Fußnoten haben, die aufeinander folgen, z.B. (25), ..., (26).
Ist das nicht so, erhältst Du einen Fehler. Es sollte dann aber trotzdem ein Output in "out2.txt" zu finden sein.
mercedesdriver schrieb:
PS: Verwendest du eine Entwicklungsumgebung? Ich hab mal eric5 ausprobiert ...
Hehe, nee ich schreibe direkt in vim. ;)

Soweit erstmal.
 
OP
A

Anonymous

Gast
Bei mir erscheint leider ein
Code:
Traceback (most recent call last):
  File "./fussnoten-in-latex.py", line 32, in <module>
    to_ = b[x]
IndexError: list index out of range

Ist das Dokument zu groß oder was hat es damit auf sich?


MfG. Mercedesdriver :)
 

abgdf

Guru
Das deutet darauf hin, daß alle Fußnoten "verbraucht" und eingefügt sind. Kann sein, daß es geklappt hat. Sieht die Datei "out2.txt" gut aus?
 
OP
A

Anonymous

Gast
Boah, du bist super! Herzlichen Dank!
Es hat geklappt (die Fehlermeldung lag wohl daran, dass ich unten die zu ersetzenden Nummer (1) ... nochmals hatte (also zweimal vorkamen. Diese gelöscht und alles ging ohne Probleme!
[edit: erledigt] Jetzt gibt es noch ein kleines Problem mit der Zeichencodierung (Umlaute) ... muss da vielleicht irgendwo was im Script definiert werden?

[edit] Klappt doch problemlos, lag daran, dass die latextext.txt in UTF8 kodiert war -- jetzt ist alles einwandfrei. Ich bin stolz auf dich ;)
Die kleinen Änderungen bzgl. Formatierung versuche ich jetzt selbst hinzubekommen (damit ich gleich das Gelernte vertiefen kann).
Ggf. melde ich mich also nochmals ...[/edit]

MfG. Mercedesdriver :)
 
OP
A

Anonymous

Gast
Hallo abgdf, ich bräuchte nochmals deine Hilfe ...
Inzwischen funktioniert ja das suchen/ersetzen einwandfrei -- nur leider ist die Textvorlage im Internet nicht korrekt, sondern an manchen Textstellen ist die Fußnote im Text nicht mit einer Klammer eingepackt (z.B. Fußnote 6).
Jetzt habe ich mal mit meinen dürftigen neuen Fähigkeiten versucht ein Script zu schreiben, das fehlende Fußnoten sucht und zur Weiterverarbeitung entsprechend anpasst (ja ich weiß, das geht im Endeffekt schneller von Hand) -- jedoch funktioniert es nicht richtig (es kommt irgendwie aus der Schleife nicht richtig raus und gibt dann die angepasste Liste nicht zurück).
Wie gesagt Kraut und Rüben:
Code:
#!/usr/bin/env python2
# coding: iso-8859-1

import os

LATEXINPUT = "zwischentext.txt"
FNINPUT = "out.txt"
OUTPUT = "out.tex"

########################
def getFile(fname):
    fh = open(os.path.join(os.getcwd(), fname), "r")
    a = fh.readlines()
    fh.close()
    for i in range(len(a)):
        a[i] = a[i].rstrip("\n")
    return a

########################
def vorbehandlung(latexliste, fussnotenliste, fussnotenindex):
    latexlisteint = latexliste
    from_ = "(" + str(fussnotenindex) + ")" # ersetze (1)
    from2_ = str(fussnotenindex) + "."
    from3_ = str(fussnotenindex) + ","
    print(str(len(latexlisteint)) + " Zeilen zu verarbeiten.")
    for i in latexlisteint:
        if from_ in i:
            print("Fussnote " + str(fussnotenindex) + " von " + str(len(fussnotenliste)) + " gefunden.")
            fussnotenindex += 1
            from_ = "(" + str(fussnotenindex) + ")"
    
    from2_ = str(fussnotenindex) + "."
    if fussnotenindex < len(fussnotenliste):
        eingabe = raw_input("Fussnote " + str(fussnotenindex) + " nicht gefunden -- suchen? [j]")
        if "j" in eingabe:
            for i in latexlisteint:
                if from2_ in i:
                    from2_ = str(fussnotenindex) + "."
                    print("Mögliche Fussnote " + str(fussnotenindex) + " gefunden in:")
                    print(i)
                    eingabe = raw_input("ersetzen? [j]")
                    if "j" in eingabe:
                        i = i.replace(from2_, " (" + str(fussnotenindex) + ").", 1)
                        fussnotenindex += 1
                        print(i)
                        latexlisteint = vorbehandlung(latexlisteint, fussnotenliste, fussnotenindex)
                    elif "n" in eingabe:
                        break
                        
    return latexlisteint
                        
########################


a = getFile(LATEXINPUT)
b = getFile(FNINPUT)


ind = 1 # mit fussnote 1 beginnen
x = 0 # zeilenzaehler
to_ = b[x] # zu fussnote ersetzen aus liste/datei

c = vorbehandlung(a, b, ind)

fh2 = open(os.path.join(os.getcwd(), OUTPUT), "w")

x = 0 # zeilenzaehler

#print(str(len(a)))
#for i in a:
#    if from_ in i:
#        i = i.replace(from_, to_, 1)
#        print("Fussnote " + str(ind) + " von " + str(len(b)) + " Zeilen verarbeitet.")
#        ind += 1
#        from_ = "(" + str(ind) + ")"
#        x += 1
#        to_ = b[x]
#    fh2.write(i + "\n")

for i in c:
    fh2.write(i + "\n")
print("geschrieben")
    
fh2.close()

Kannst du mal drüberschauen und die Fehler ausmerzen?


MfG. Mercedesdriver :)
 

abgdf

Guru
mercedesdriver schrieb:
nur leider ist die Textvorlage im Internet nicht korrekt, sondern an manchen Textstellen ist die Fußnote im Text nicht mit einer Klammer eingepackt (z.B. Fußnote 6).
Tja, anhand welchen Kriteriums willst Du die Fußnote dann im Text identifizieren? Irgendein Kriterium braucht man ja, sonst kann man keinen Algorithmus dazu schreiben.
Was ich Dir anbieten könnte, wäre ein Skript, das die nicht korrekt gesetzten Fußnoten automatisch findet und anzeigt:
Code:
#!/usr/bin/env python2
# coding: iso-8859-1

import os

INPUTFILE  = "vat-ii_const_19641121_lumen-gentium_ge.html"
NROFFN = 195

def getFile(fname):
    fh = open(os.path.join(os.getcwd(), fname), "r")
    a = fh.readlines()
    fh.close()
    for i in range(len(a)):
        a[i] = a[i].rstrip("\n")
    return a

a = getFile(INPUTFILE)

# Nur den Teil vor den Fußnoten untersuchen, Dokument also zerteilen:
a = a[:a.index("<p><b>Anmerkungen</b>: </p>")]

for i in range(1, NROFFN, 1):
    found = False
    tofind = "(" + str(i) + ")"
    for u in a:
        if tofind in u:
            found = True
            break
    if not found:
        print "Nicht gefunden: " + tofind
Dann weiß man, wo im Dokument noch Hand anzulegen ist. ;)
Ausgabe ist bei mir:
Code:
Nicht gefunden: (6)
Nicht gefunden: (7)
Nicht gefunden: (21)
Nicht gefunden: (28)
Nicht gefunden: (39)
Nicht gefunden: (52)
Nicht gefunden: (105)
Nicht gefunden: (113)
Nicht gefunden: (114)
Nicht gefunden: (122)
Nicht gefunden: (123)
Nicht gefunden: (124)
Nicht gefunden: (125)
Nicht gefunden: (132)
HTH
 
OP
A

Anonymous

Gast
@ abgdf: Ja ich glaube dieses Vorgehen ist sinnvoller -- warum einfach, wenns auch kompliziert geht ;)
@ Roland: Vielen Dank, die Seite kannte ich sogar -- aber auch auf dieser bleibt die Problematik mit dem ins LaTeX übersetzen. Aber grundsätzlich ist das sogar eine sauberere Ausgangsdatei. Werde wohl mit der weiter arbeiten. Danke.

Ich glaube ich lass es einfach mal dabei, sonst wende ich da noch mehr Zeit auf, als wenn ich die ganzen Texte dreimal durchlesen ...

MfG. Mercedesdriver :)
 
Oben