In AsciiDoc gibt es keine Möglichkeit, eigene Makros zu definieren. Makros erzeugen Testblöcke, die über ein target und attributes parametrisiert werden können.
Beispiele für vorhandene Makros sind
include::Example.cs[tag=ExampleConstructor,indent=0] image::image.jpg[250,150,float=left,scaledwidth=25%]
Allgemein haben Makros den Aufbau <name>::<target>[<attrlist>]
.
Makros auf Blockebene werden mit ::
definiert, inline Makros mit :
.
Es gibt allerdings keine Möglichkeit, eigene Makros zu definieren (mit Ausnahme von in Roby geschriebenen Modulen).
Da AsciiDoc ein textbasierendes Format ist, kann jedoch ein Programm vorgeschalten werden, das folgendes macht:
-
Einlesen der Textdatei
-
Suchen nach Strings mit dem Aufbau
^(?<name>[a-zA-Z0-9-_])::(?<target>)?\[(?<attributes>[^\]]*)\]
Dieser Ausdruck erkennt alle Blockmakros, die am Zeilenanfang stehen. -
Ersetzen durch anderen, im Programm generierten, Inhalt.
Im Verzeichnis Preprocessor ist eine allgemeine C# Implementierung, die die obigen Schritte schon umsetzt. Über eine übergebene Funktion kannst du Methoden für einzelne Makros definieren und das Programm so erweitern. Die Datei Proram.cs ist so aufgebaut:
public static async Task<int> Main(string[] args)
{
try
{
var preprocessor = AsciidocPreprocessor.FromFile(args[0]); // (1)
preprocessor.AddMacroProcessor("example_macro", ExampleMacroProcessor); // (2)
var newContent = await preprocessor.Process(); // (3)
Console.WriteLine(newContent);
return 0;
}
catch (Exception e)
{
Logger.LogError(e.InnerException?.Message ?? e.Message);
return 1;
}
}
static string ExampleMacroProcessor
(string target, Attributes attributes, Dictionary<string, string> globalVariables)
{
return @$"
[source,html]
----
<img src=""{target}"" width=""{attributes[0]}"" height=""{attributes[1]}"" style=""width: {attributes["css_width"]}"">
----
";
}
-
Die zu lesende AsciiDoc Datei wird als Argument übergeben.
-
Die Methode
AddMacroProcessor
erwartet 2 Parameter. Der erste Parameter ist der Name des Makros, wie er 1:1 in der AsciiDoc Datei verwendet wird. Die 2 Funktion ist eine Funktion, die 3 Parameter bekommt (siehe unten). -
Hier wird die Verarbeitung gestartet.
💡
|
Es gibt auch eine Methode AddAsyncMacroProcessor für einen async Processor.
|
Die Methode ExampleMacroProcessor
ist ein Beispiel für eine solche Erweiterung.
Sie bekommt 3 Parameter:
- target
-
Wert des Targets im Makro. Beispiel:
my_macro::Example.cs[tag=ExampleConstructor,indent=0]
liefert Example.cs - attributes
-
Attributklasse, die den einfachen Zugriff auf Attribute bereitstellt. Der Indexoperator ist überladen. Ist der Index vom Typ
int
, wird das Attribut an der entsprechenden Stelle zurückgegeben (0 basierend).Ist der Index vom Typ
string
, wird der Wert eines Attributes mit Namen zurückgegeben.Beispiel
my_macro::imagefile.jpg[250,150,float=left,scaledwidth=25%]
-
attributes[0] 250
-
attributes[1] 150
-
attributes[2] float=left
-
attributes[3] scaledwidth=25%
-
attributes["float"] left
-
attributes["scaledwidth"] 25%
Du kannst über das Property
AttributesArray
undNamedAttributes
direkt auf das darunterliegende Array bzw. Dictionary zugreifen.
-
- globalVariables
-
Ein Dictionary, in dem alle globalen Variablen (z. B.
:author: value
) abrufbar sind.
❗
|
Um den Preprocessor zu verwenden, benötigst du die .NET 8 SDK.
Du kannst dies mit dem Befehl dotnet --list-sdks überprüfen.
|
Erstelle in einem Verzeichnis eine AsciiDoc Datei. Kopiere dann das Verzeichnis Preprocessor in dieses Verzeichnis. Du kannst das Verzeichnis Preprocessor auch in ein globales Verzeichnis kopieren. Mit dem convert_adoc.cmd Skript kannst du den Parameter --processor übergeben, der den Pfad zur Preprocessor Anwendung angibt.
convert_adoc.cmd my_file.adoc my_file.pdf --processor Preprocessor
./convert_adoc.sh my_file.adoc my_file.pdf --processor Preprocessor
In my_file.processed.adoc findest du die Ausgabe des Preprocessors. Diese Datei wird dann den nachfolgenden Befehlen übergeben.
Im Preprocessor ist auch ein Makro chatgpt_prompt
integriert.
In der Datei Program.cs wird dieser geladen, wenn eine Datei chatgpt_key.txt vorhanden ist.
📎
|
Dieser Preprocessor braucht einen API Key von OpenAI, der allerdings kostenpflichtig ist. Kopiere diesen Key in die Datei chatgpt_key.txt. Die Datei muss ich im Ordner des AsciiDoc Dokumentes befinden. |
|
Schließe die Datei über eine .gitignore Datei aus, wenn du das Dokument in einem Repository verwaltest. |
Das Makro hat folgenden Aufbau
chatgpt_prompt::["Analysiere rhetorische Stilmittel zu folgendem Artikel: https://www.diepresse.com/19123344/dividenden-wurde-ktm-ausgeraeumt ",max_tokens=8192,temperature=0,resolve_links=true,save_message=true]
Das Target ist leer. Das erste Attribut ist der Prompt. Zusätzlich können mehrere Attribute definiert werden.
- max_tokens
-
Die Abrechnung basiert über sogenannte Token. 1000 Token entsprechen ca. 1.5 Cent und umfasst 750 Worte. Es gibt pro Modell eine Maximalgrenze von rd. 10000 Token. Ist der Wert zu hoch, liefert die API bad request.
- temperature
-
Steuert, wie "kreativ" das Modell ist.
-
Niedrige Werte (z. B. 0.0 bis 0.3): Das Modell wird deterministischer und fokussierter. Es bevorzugt die wahrscheinlichste Antwort und reduziert die Variation. Ideal für Aufgaben, bei denen Genauigkeit und Konsistenz entscheidend sind, z. B.:
-
Mathematik
-
Faktenbasierte Antworten
-
Code-Generierung
-
-
Mittlere Werte (z. B. 0.4 bis 0.7): Das Modell wird kreativer, bleibt aber noch weitgehend kontrolliert. Nützlich für Anwendungen, die sowohl Kreativität als auch Relevanz erfordern, z. B.:
-
Schreiben von E-Mails
-
Generierung von Blog-Artikeln
-
Content-Erstellung mit klaren Vorgaben
-
-
Hohe Werte (z. B. 0.8 bis 1.0 oder höher): Das Modell wird viel kreativer und erzeugt originelle, oft überraschende Inhalte. Antworten können inkonsistenter sein oder weniger präzise, aber dafür unerwarteter. Gut geeignet für:
-
Brainstorming
-
Kreatives Schreiben
-
Anwendungen, bei denen Vielfalt bevorzugt wird
-
-
- resolve_links=true
-
Über die API können keine Hyperlinks aufgelöst werden. Mit dieser Option fordert das C# Programm über die Klasse
HttpClient
die Inhalte an, löscht die HTML Syntaxelemente und ersetzt den Link durch den Text, bevor er an ChatGPT gesendet wird. Dies funktioniert nur für Links, die Textdokumente zurückgeben.
📎
|
Schreibe die Links in eine eigene Zeile und ohne Punkt (.) am Ende.
Alles von http(s)?:// bis zur nächsten Leerstelle wird als Link interpretiert.
|
- save_message=true
-
Die API ist stateless, das bedeutet dass der Prompt nicht das Ergebnis der vorigen Prompts zur Verarbeitung einschließt. Mit dieser Option wird die Antwort gespeichert und automatisch bei nachfolgenden Requests zum Prompt angefügt.
💡
|
Verwende die Option nur bei Prompts, die nachfolgende Werte beeinflussen. Sie vergrößert den Prompt, die Anfragen kosten dann mehr Tokens. |
Folgender Prompt wird immer mitgeliefert:
Du spricht mit einem Computerprogramm, das nur AsciiDoc versteht. Es dürfen keine anderen Inhalte von dir übermittelt werden. Source code soll in einen [source] Block mit der entsprechenden Programmiersprache stehen und mit der Option linenums versehen werden. Achte darauf, dass Callouts immer in spitzen Klammern stehen. PlantUML Diagramme sind in einem Codeblock mit [plantuml,,svg] ohne Callouts zu übermitteln. Es darf kein Titel (mit einem = beginnend) übermittelt werden.
Die Promots und die Antworten werden in die Datei chatgpt_cache.json geschrieben. Wenn der Prompt unverändert ist, wird beim neuerlichen Verarbeiten der Datei die Antwort aus dem Cache genommen. Falls du Prompts mit der Option save_message änderst, oder nicht erwartete Antworten erhältst, empfiehlt es sich, diese Datei zu löschen.
Um die Verwendung zu demonstrieren, gibt es folgende Beispiele.
📎
|
Achte darauf, dass sich die Datei chatgpt_key.txt im Verzeichnis des AsciiDoc Dokumentes befindet. |
- [preprocessor_simple_test.adoc]
-
Ruft das vordefinierte Makro example_macro im Preprocessor Programm auf. Aufruf:
convert_adoc.cmd preprocessor_simple_test.adoc preprocessor_simple_test.pdf --processor Preprocessor
Die Zwischendatei ist in preprocessor_simple_test.processed.adoc zu finden.
- [preprocessor_test.adoc]
-
Verwendet das ChatGPT Makro, um eine Datenbank Aufgabenstellung zu bearbeiten. API Key erforderlich! Aufruf:
convert_adoc.cmd preprocessor_test.adoc preprocessor_test.pdf --processor Preprocessor
Die Zwischendatei ist in preprocessor_test.processed.adoc zu finden.
- [kommentar.adoc]
-
Verwendet das ChatGPT Makro, um einen Kommentar auf Basis der URL eines Artikels zu verfassen. API Key erforderlich! Aufruf:
convert_adoc.cmd kommentar.adoc kommentar.pdf --processor Preprocessor
Die Zwischendatei ist in kommentar.processed.adoc zu finden.