NAME

Quiq::Section::Parser - Parser für Abschnitte

BASE CLASS

Quiq::Hash

DESCRIPTION

Ein Objekt der Klasse repräsentiert einen Parser für "Abschnitte".

Syntax

Ein Abschnitt hat den Aufbau:

# [IDENTIFIER]

KEY:
    VALUE
...

CONTENT
IDENTIFIER

Abschnittsbezeichner.

KEY

Schlüssel. Ein Abschnitt kann beliebig viele Schlüssel/Wert-Paare definieren.

VALUE

Wert. Ist mit einer bestimmten Tiefe an Whitespace eingerückt. Kann mehrzeilig sein.

CONTENT

Inhalt. Ist typischerweise mehrzeilig. Es kann höchstens einen Inhalt je Abschnitt geben.

ATTRIBUTES

encoding => $charset (Default: undef)

Dekodiere Input gemäß Zeichensatz.

sectionRegex => $regex (Default: qr/^# (<\w+>|\[\w+\]|\(\w+\)|\{\w+\})/)

Muster für die erste Zeile eines Abschnitts.

defaultSection => $section (Default: undef)

Default für die erste Zeile eines Abschnitts. Diese Option kann gesetzt werden, wenn eine Datei aus nur einem Abschnitt besteht und daher keine einleitende Zeile notwendig ist.

keyRegex => $regex (Dafault: qr/^(\w+):$/)

Muster für eine Schlüssel-Zeile.

sourceNotNeeded => $bool (Default: 0)

Speichere den geparsten Quelltext nicht im Abschnittsobjekt. Dies spart Speicherplatz, wenn der Quelltext nicht gebraucht wird.

startLine => $line (Default: "--BEGIN--\n")

Startzeile für den Inhalt.

parsedSections

Anzahl der geparsten Abschnitte. Das Attribut kann nur abgefragt werden.

parsedLines

Anzahl der geparsten Zeilen. Das Attribut kann nur abgefragt werden.

parsedChars

Anzahl der geparsten Zeichen. Das Attribut kann nur abgefragt werden.

parsedBytes

Anzahl der geparsten Bytes. Das Attribut kann nur abgefragt werden.

METHODS

Konstruktor

new() - Konstruktor

Synopsis

$par = $class->new(@keyVal);

Returns

Referenz auf Parser-Objekt

Description

Instantiiere ein Parser-Objekt mit den Parser-Attributen @keyVal. In abgeleiteten Klassen kann der Konstruktor überschrieben und eine andere Attribut-Initialisierung vorgenommen werden.

Parsing

parse() - Parse Abschnitte

Synopsis

$objA|@objs = $par->parse(undef[,$sub]);
$objA|@objs = $par->parse($file[,$sub]);
$objA|@objs = $par->parse(\$text[,$sub]);

Arguments

$file

Name der Eingabedatei. Ist der Parameter undef oder ein Leerstring oder '-', wird die Eingabe von STDIN gelesen.

\$text

Lies die Eingabe vom String ("In-Memory-File") $text.

$sub

Anonyme Callback-Funktion, die nach jedem geparsten Abschnitt aufgerufen wird. Die Funktion bekommt die geparste Information in Form einzelner Parameter übergeben, instantiiert ein Objekt und liefert dieses zurück. Alle Objekte werden von der Methode parse() gesammelt und am Ende zurückgeliefert. Die Klasse des Objektes ist nicht festgelegt. Wird kein Objekt geliefert, wird der Return-Wert von parse() ignoriert.

Ist der Parameter $sub nicht angegeben, wird folgende Default-Definition genutzt:

sub {
    # @_: $type,$keyValH,$keyA,$content,$source,$file,$lineNumber
    return Quiq::Section::Object->new(@_);
}

Returns

Liste der Abschnittsobjekte (Array-Kontext) oder Referenz auf die Liste (Skalar-Kontext).

Description

Parse die Eingabe und liefere die Liste der Abschnittsobjekte zurück. Die Eingabe besteht aus einer Folge von 0 bis n Syntax. Die Methode kann wiederholt mit verschiedenen Eingaben aufgerufen werden.

Events

section() - Verarbeite Abschnitt

Synopsis

$obj = $par->section($identifier,$keyValH,$keyA,$content,$source,$file,$lineNumber);

Arguments

$identifier

Abschnitts-Bezeichner einschließlich Klammern.

$keyValH

Referenz auf Schlüssel/Wert-Hash.

$keyA

Referenz auf Schlüssel-Array.

$content

Der Inhalt.

$source

Der Quelltext des Abschnitts.

$file

Der Name der Datei, die den Abschnitt enthält. Im Falle einer In-Memory-Datei "(source)".

$lineNumber

Die Zeilennummer, an der der Abschnitt in der Datei beginnt.

Returns

Nichts oder Abschnitts-Objekt

Description

Die Methode wird vom Parser für jeden vollständig geparsten Abschnitt gerufen.

Details

Die Methode instantiiert per Default ein Objekt der Klasse Quiq::Section::Object und liefert eine Referenz auf dieses Objekt zurück. Das Objekt wird zur Liste der Abschnittsobjekte hinzugefügt. Die Liste der Abschnittsobjekte wird von der Methode parse() zurückgeliefert. In abgeleiteten Klassen kann die Methode überschrieben und ein anderes Verhalten implementiert werden.

error() - Behandele Fehler

Synopsis

$par->error($@,$source,$file,$lineNumber);

Arguments

$@

Die Exception.

$source

Der Quelltext des Abschnitts bis zur Exception.

$file

Der Name der Datei, die den Abschnitt enthält. "(source)" im Falle einer In-Memory-Datei.

$lineNumber

Die Zeilennummer, bei der die Exception ausgelöst wurde.

Returns

Die Methode kehrt nicht zurück

Description

Die Methode wird vom Parser im Fehlerfall gerufen.

Details

Die Methode empfängt die betreffende Exception und erzeugt eine neue Exception, die um Angaben zur Fehlerstelle angereichert ist. In abgeleiteten Klassen kann die Methode überschrieben und ein anderes Verhalten implementiert werden.

DETAILS

Klammerung IDENTIFIER

Anstelle der eckigen Klammern [] kann der Abschnittsbezeichner IDENTIFIER per Default auch in spitze <>, runde () oder geschweifte Klammern {} eingefasst sein. Das Muster kann durch Überschreiben des Parser-Attributs sectionRegex=>$regex geändert werden.

Einrücktiefe VALUE

Die Einrücktiefe der VALUE-Zeilen ermittelt der Parser anhand der ersten Zeile des ersten Schlüssel/Wert-Paars der Datei. Alle weiteren Werte in der Datei müssen in der gleichen Tiefe eingerückt sein.

KEY-Zeile auskommentieren

KEY-Zeilen können auskommentiert werden, indem zwei Ausrufungszeichen !! gefolgt von mindestens einem Leerzeichen an den Anfang der Zeile gesetzt werden. Einschränkung: Die erste KEY-Zeile kann nicht auskommentiert werden, da sie den betreffenden KEY/VALUE-Abschnitt einleitet. Beispiel (dargestellt mit Pipe- statt Ausrufungszeichen):

Name:
    width

|| BriefDescription:
||     Liefere die Breite und Höhe des Bildes

Ergebnis:

Name:
    width

VALUE auskommentieren

VALUE-Zeilen können ganz oder teilweise auskommentiert werden. Eine ganze VALUE-Zeile wird wie eine KEY-Zeile auskommentiert (s.o.). Ein Teil wird auskommentiert, indem mindestens ein Leerzeichen gefolgt von zwei Ausrufungszeichen gefolgt von einem Leerzeichen in eine VALUE-Zeile eingefügt wird. Ab dem ersten Leerzeichen werden bis zum Ende der Zeile alle Zeichen ignoriert. Beispiel (mit Pipe- statt Ausrufungszeichen):

Imports:
    || Old::Hash
    New::Hash || neue Hash-Klasse

Ergebnis:

Imports:
    New::Hash

Start-Zeichenkette CONTENT

Beginnt CONTENT mit einer Zeile, die wie eine KEY:-Zeile aussieht, oder sind Leerzeilen am Anfang von CONTENT signifikant, muss der Anfang von CONTENT mit einer Start-Zeichenkette gekennzeichnet werden. Die Start-Zeichenkette ist --BEGIN-- oder # --- mit drei oder mehr Bindestrichen bis zum Ende der Zeile. Folgt auf eine # ----Zeile eine Leerzeile, wird diese übergangen, also nicht zum Inhalt hinzugezählt. Dies ist bei --BEGIN-- nicht der Fall.

Stop-Zeichenkette CONTENT

Enthält CONTENT eine Zeile, die wie der Anfang eines Abschnitts aussieht (welcher CONTENT per Default beendet) oder sind Leerzeilen am Ende von CONTENT signifikant, muss dessen Ende mit einer Stop-Zeichenkette gekennzeichnet werden. Sie Stop-Zeichenkette wird durch Schlüssel/Wert-Paar Stop: definiert:

Stop:
    --END--

Stop: ist eine Parser-Direktive, die nur für den Abschnitt gilt, in dem sie definiert ist. Die Stop-Zeichenkette beendet CONTENT und zählt nicht zum CONTENT hinzu.

Datei mit einem einzelnen Abschnitt

Besteht eine Datei aus einem einzelnen Abschnitt, kann die Abschnitts-Einleitungszeile

# IDENTIFIER

weggelassen werden, wenn IDENTIFIER (mit Klammerung) als Default-Section definiert wird:

$par = Quiq::Section::Parser->new(
    defaultSection => $identifier,
    ...
);

Als Beispiel siehe quiq-confluence:

my $par = Quiq::Section::Parser->new(
    defaultSection => '[ConfluencePage]',
);
my ($sec) = $par->parse($file);

VERSION

1.220

AUTHOR

Frank Seitz, http://fseitz.de/

COPYRIGHT

Copyright (C) 2024 Frank Seitz

LICENSE

This code is free software; you can redistribute it and/or modify it under the same terms as Perl itself.