suchen
HeimWeb-FrontendCSS-TutorialSo modifizieren Sie Knoten in einem abstrakten Syntaxbaum

So modifizieren Sie Knoten in einem abstrakten Syntaxbaum

Eines der leistungsstärkeren Konzepte, über die ich in letzter Zeit gestoßen bin, ist die Idee von abstrakten Syntaxbäumen oder ASTs. Wenn Sie jemals Alchemie studiert haben, erinnern Sie sich vielleicht, dass die gesamte Motivation für Alchemisten darin bestand, einen Weg zu entdecken, um nicht gold in Gold durch wissenschaftliche oder arkane Methoden zu verwandeln.

ASTS sind so etwas. Mit ASTS können wir Markdown in HTML, JSX in JavaScript und vieles mehr verwandeln.

Warum sind ASTS nützlich?

Zu Beginn meiner Karriere habe ich versucht, Dateien mithilfe einer Find-and-Replace-Methode zu ändern. Dies war ziemlich kompliziert, daher habe ich versucht, reguläre Ausdrücke zu verwenden. Am Ende gab ich die Idee auf, weil sie so spröde war; Die App brach die ganze Zeit, weil jemand in eine Weise, die ich nicht erwartet hatte, in Text eindrang und meine regulären Ausdrücke brechen würde, was dazu führte, dass die gesamte App nach unten fiel.

Der Grund, warum dies so schwierig war, ist, dass HTML flexibel ist. Das macht es extrem schwierig, mit regulären Ausdrücken zu analysieren. Ein solcher String-basiertes Ersatz ist anfällig für Brechen, da es möglicherweise ein Match verpasst, zu viel übereinstimmt oder etwas Seltsames tut, das zu einem ungültigen Markup führt, das die Seite aussieht.

ASTS Andererseits verwandeln Sie HTML in etwas weitaus strukturierteres, was es viel einfacher macht, in einen Textknoten einzutauchen und nur diesen Text zu ersetzen oder sich mit Elementen zu vermeiden, ohne sich überhaupt mit dem Text zu befassen.

Dies macht die AST-Transformation sicherer und weniger fehleranfälliger als eine rein stringbasierte Lösung.

Wofür werden ASTS verwendet?

Schauen wir uns zunächst ein minimales Dokument mit ein paar Markdown -Zeilen an. Dies wird als Datei namens home.md gespeichert, die wir im Inhaltsordner unserer Website speichern werden.

 # Hallo Welt!

! [Cardigan Corgi] (<https:>) Ein entzückender Corgi!

Ein weiterer Text geht hier.</https:>

Angenommen, wir wissen, dass wir Markdown kennen, können wir schließen, dass bei diesem Markdown ein H1 -Tag mit der Aufschrift "Hallo Welt!" Dann zwei Texteabsätze: Das erste enthält ein Bild eines Corgi und einige Text, die es beschreiben sollen, und der zweite sagt: "Ein weiterer Text geht hier."

Aber wie wird es von Markdown zu HTML verwandelt?

Hier kommen Asts ins Spiel!

Da es mehrere Sprachen unterstützt, werden wir die Unist Cloe -Syntax -Baumspezifikation und insbesondere das Projekt einheitlich verwenden.

Installieren Sie die Abhängigkeiten

Zunächst müssen wir die Abhängigkeiten installieren, die erforderlich sind, um den Markdown in einen AST zu analysieren und sie in HTML umzuwandeln. Dazu müssen wir sicherstellen, dass wir den Ordner als Paket initialisiert haben. Führen Sie den folgenden Befehl in Ihrem Terminal aus:

 # Stellen Sie sicher, dass Sie sich in Ihrem Root -Ordner befinden (wo `content` ist)
# Initialisieren Sie diesen Ordner als NPM -Paket
npm init

# Die Abhängigkeiten installieren
NPM Installieren Sie einheitliche Bemerkung-Parse-Bemerkung-HTML

Wenn wir davon ausgehen, dass unser Markdown in Home.md gespeichert ist, können wir den AST mit dem folgenden Code erhalten:

 const fs = erfordern ('fs');
const Unified = fordert ('Unified');
const markdown = erfordern ('Bemerkung-Parse');
const html = require ('Remark-html');

const Inhalt = Unified ()
  .use (Markdown)
  .use (html)
  .ProcessSync (fs.readFilesync (`$ {process.cwd ()}/content/home.md`))
  .ToString ();

console.log (Inhalt);

Dieser Code nutzt das integrierte FS-Modul des Knotens, mit dem wir auf das Dateisystem zugreifen und manipulieren können. Weitere Informationen dazu finden Sie in den offiziellen Dokumenten.

Wenn wir dies als src/index.js speichern und Knoten verwenden, um dieses Skript aus der Befehlszeile auszuführen, werden wir Folgendes in unserem Terminal sehen:

 $ node src/index.js 
<h1 id="Hallo-Welt"> Hallo Welt! </h1>
<p> <img src="<https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg>" alt="Cardigan Corgi"> ein entzückender Corgi! </p>
<p> Ein weiterer Text geht hier. </p>

Wir sagen Unified, dass es Bemering-Parse verwenden soll, um die Markdown-Datei in ein AST zu verwandeln und dann Remarkdml zu verwenden, um das Markdown-AST in eine HTML zu verwandeln-oder insbesondere in etwas, das sie in eine sogenannte VFILE verwandelt. Mit der Methode toString () verwandelt wir diese AST in eine tatsächliche Zeichenfolge von HTML, die wir im Browser anzeigen können!

Dank der harten Arbeit der Open-Source-Community macht die Bemerkung die harte Arbeit, sich für uns in HTML zu verwandeln. (Siehe Diff)

Schauen wir uns als nächstes an, wie dies tatsächlich funktioniert.

Wie sieht ein AST aus?

Um das eigentliche AST zu sehen, schreiben wir ein winziges Plugin, um es zu protokollieren:

 const fs = erfordern ('fs');
const Unified = fordert ('Unified');
const markdown = erfordern ('Bemerkung-Parse');
const html = require ('Remark-html');

const Inhalt = Unified ()
	.use (Markdown)
  .use (() => tree => console.log (json.Stringify (Baum, NULL, 2)))
	.use (html)
	.ProcessSync (fs.readFilesync (`$ {process.cwd ()}/content/home.md`))
	.ToString ();

Die Ausgabe des Ausführens des Skripts wird jetzt sein:

 {
  "Typ": "root",
  "Kinder": [
    {
      "Typ": "Überschrift",
      "Tiefe": 1,,
      "Kinder": [
        {
          "Typ": "Text",
          "Wert": "Hallo Welt!",
          "Position": {}
        }
      ],
      "Position": {}
    },
    {
      "Typ": "Absatz",
      "Kinder": [
        {
          "Typ": "Bild",
          "Titel": NULL,
          "URL": "<https:>",
          "Alt": "Cardigan Corgi",
          "Position": {}
        },
        {
          "Typ": "Text",
          "Wert": "Ein entzückender Corgi!",
          "Position": {}
        }
      ],
      "Position": {}
    },
    {
      "Typ": "Absatz",
      "Kinder": [
        {
          "Typ": "Text",
          "Wert": "Ein weiterer Text geht hier.",,
          "Position": {}
        }
      ],
      "Position": {}
    }
  ],
  "Position": {}
}</https:>

Beachten Sie, dass die Positionswerte abgeschnitten wurden, um Platz zu sparen. Sie enthalten Informationen darüber, wo sich der Knoten im Dokument befindet. Für die Zwecke dieses Tutorials werden wir diese Informationen nicht verwenden. (Siehe Diff)

Dies ist ein wenig überwältigend anzusehen, aber wenn wir zoomen, können wir feststellen, dass jeder Teil des Markas zu einem Knotentyp mit einem Textknoten darin wird.

Zum Beispiel wird die Überschrift:

 {
  "Typ": "Überschrift",
  "Tiefe": 1,,
  "Kinder": [
    {
      "Typ": "Text",
      "Wert": "Hallo Welt!",
      "Position": {}
    }
  ],
  "Position": {}
}

Folgendes bedeutet dies:

  • Der Typ sagt uns, mit welcher Art von Knoten wir es zu tun haben.
  • Jeder Knotentyp hat zusätzliche Eigenschaften, die den Knoten beschreiben. Die Tiefeneigenschaft auf der Überschrift sagt uns, welche Ebene sie ist - eine Tiefe von 1 bedeutet, dass es sich um ein

    -Tags handelt, 2 bedeutet

    und so weiter.

  • Das Kinderarray sagt uns, was sich in diesem Knoten befindet. Sowohl in der Überschrift als auch im Absatz gibt es nur Text, aber wir konnten hier auch Inline -Elemente wie sehen.

Dies ist die Kraft von ASTS: Wir haben jetzt das Markdown -Dokument als Objekt beschrieben, das ein Computer verstehen kann. Wenn wir dies wieder auf Markdown ausdrucken möchten, würde ein Markdown -Compiler wissen, dass ein „Überschrift“ -Knoten mit einer Tiefe von 1 mit # beginnt, und ein untergeordneter Textknoten mit dem Wert „Hallo“ bedeutet, dass die endgültige Zeile # Hallo sein sollte.

Wie AST -Transformationen funktionieren

Die Transformation eines AST wird normalerweise mit dem Besuchermuster durchgeführt. Es ist nicht wichtig zu wissen, wie dies produktiv ist, aber wenn Sie neugierig sind, hat JavaScript -Designmuster für Menschen von Soham Kamani ein großartiges Beispiel, um zu erklären, wie es funktioniert. Das Wichtigste ist, dass die meisten Ressourcen für AST -Arbeit über „Besuchsknoten“ sprechen werden, die sich grob übersetzt, um „einen Teil des AST zu finden, damit wir Dinge damit machen können“. Die Art und Weise, wie diese Funktionen üben, ist, dass wir eine Funktion schreiben, die auf AST -Knoten angewendet wird, die unseren Kriterien entsprechen.

Ein paar wichtige Anmerkungen darüber, wie es funktioniert:

  • ASTS kann riesig sein, daher werden wir aus Leistungsgründen Knoten direkt mutieren. Dies entspricht, wie ich normalerweise die Dinge nähere - als allgemeine Regel, die ich nicht gerne den globalen Zustand mutiere -, aber es macht in diesem Zusammenhang Sinn.
  • Besucher arbeiten rekursiv. Das heißt, wenn wir einen Knoten verarbeiten und einen neuen Knoten desselben Typs erstellen, wird der Besucher auch auf dem neu erstellten Knoten ausgeführt, es sei denn, wir sagen dem Besucher ausdrücklich.
  • Wir werden in diesem Tutorial nicht zu tief gehen, aber diese beiden Ideen werden uns helfen zu verstehen, was los ist, wenn wir uns mit dem Code anlegen.

Wie modifiziere ich die HTML -Ausgabe des AST?

Was ist jedoch, wenn wir die Ausgabe unseres Markdowns ändern wollen? Nehmen wir an, unser Ziel ist es, Bild -Tags mit einem Figurenelement zu wickeln und eine Bildunterschrift wie folgt zu liefern:

 <abus>
  <img src="<https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg>" alt="Cardigan Corgi">
  <figcaption> ein entzückender Corgi! </figcaption>
</abus>

Um dies zu erreichen, müssen wir die HTML -AST - nicht den Markdown -AST - verwandeln, da Markdown keine Möglichkeit zum Erstellen von Figuren oder Figcaptions -Elementen hat. Glücklicherweise können wir das tun, ohne eine Reihe von benutzerdefinierten Code zu schreiben, da Unified mit mehreren Parsers interoperabel ist.

Konvertieren Sie einen Markdown AST in ein HTML AST

Um den Markdown AST in ein HTML-AST umzuwandeln, fügen Sie Bemerkung zum Rehen zu und wechseln Sie zur Rehyped-Stringify, um das AST wieder an HTML zu wenden.

 NPM installieren

Nehmen Sie die folgenden Änderungen in SRC/Index.js vor, um auf Rehypen umzusteigen:

 const fs = erfordern ('fs');
const Unified = fordert ('Unified');
const markdown = erfordern ('Bemerkung-Parse');
const merking2Rehype = fordert ('Bemerkenseiter');
const html = require ('rehype-stringify');

const Inhalt = Unified ()
	.use (Markdown)
  .
	.use (() => tree => console.log (json.Stringify (Baum, NULL, 2)))
	.use (html)
	.ProcessSync (fs.readFilesync ('Corgi.md'))
	.ToString ();

console.log (Inhalt);

Beachte

Wenn wir das Skript ausführen, sehen wir das Bildelement jetzt im AST so aus:

 {
  "Typ": "Element",
  "Tagname": "img",
  "Eigenschaften": {
    "src": "https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg",
    "Alt": "Cardigan Corgi"
  },
  "Kinder": [],
  "Position": {}
}

Dies ist der AST für die HTML -Darstellung des Bildes, sodass wir es ändern können, um das Figurenelement zu verwenden. (Siehe Diff)

Schreiben Sie ein Plugin für Unified

Um unser IMG -Element mit einem Figurenelement zu wickeln, müssen wir ein Plugin schreiben. In Unified werden Plugins mit der Methode Use () hinzugefügt, die das Plugin als erstes Argument und alle Optionen als zweites Argument akzeptiert:

 .use (Plugin, Optionen)

Der Plugin -Code ist eine Funktion (als "Anzug" in Unified Jargon bezeichnet), die die Option erhält. Diese Optionen werden verwendet, um eine neue Funktion (als „Transformator“ bezeichnet) zu erstellen, die das AST empfängt und sie erledigt. Weitere Informationen zu Plugins finden Sie im Plugin -Überblick in den einheitlichen Dokumenten.

Die von ihr zurückgegebene Funktion erhält das gesamte AST als Argument und gibt nichts zurück. (Denken Sie daran, ASTS werden global mutiert.) Erstellen Sie eine neue Datei namens iMG-to-figure.js im selben Ordner wie index.js und geben Sie dann Folgendes innen ein:

 module.exports = options => baum => {
  console.log (Baum);
};

Um dies zu verwenden, müssen wir es zu src/index.js hinzufügen:

 const fs = erfordern ('fs');
const Unified = fordert ('Unified');
const markdown = erfordern ('Bemerkung-Parse');
const merking2Rehype = fordert ('Bemerkenseiter');
const html = require ('rehype-stringify');
const imgtofigure = require ('./ img-to-figure');

const Inhalt = Unified ()
  .use (Markdown)
  .
  .use (imgtofigure)
  .ProcessSync (fs.readFilesync ('Corgi.md'))
  .ToString ();

console.log (Inhalt);

Wenn wir das Skript ausführen, sehen wir den gesamten Baum in der Konsole angemeldet:

 {
  Typ: 'root',
  Kinder: [
    {
      Typ: 'Element',
      Tagname: 'P',
      Eigenschaften: {},
      Kinder: [Array],
      Position: [Objekt]
    },
    {Typ: 'Text', Wert: '\\ n'},,
    {
      Typ: 'Element',
      Tagname: 'P',
      Eigenschaften: {},
      Kinder: [Array],
      Position: [Objekt]
    }
  ],
  Position: {
    Start: {Zeile: 1, Spalte: 1, Offset: 0},
    Ende: {Zeile: 4, Spalte: 1, Offset: 129}
  }
}

(Siehe Diff)

Fügen Sie dem Plugin einen Besucher hinzu

Als nächstes müssen wir einen Besucher hinzufügen. Dadurch werden wir tatsächlich in den Code gelangen. Unified nutzt eine Reihe von Dienstprogrammpaketen, die alle mit Unist-util-*vorangestellt sind, die es uns ermöglichen, gemeinsam mit unserem AST-Schreiben gemeinsame Dinge zu tun, ohne benutzerdefinierten Code zu schreiben.

Wir können Unist-util-vis-vis-vis-optimieren. Dies gibt uns einen Besuchshelfer, der drei Argumente nimmt:

  • Mit dem gesamten AST, mit dem wir arbeiten
  • Eine Prädikatfunktion, um zu identifizieren, welche Knoten wir besuchen möchten
  • Eine Funktion, um Änderungen am AST vorzunehmen, den wir vornehmen möchten

Führen Sie zum Installieren Folgendes in Ihrer Befehlszeile aus:

 NPM Installieren Sie Unist-util-vis

Lassen Sie uns einen Besucher in unserem Plugin implementieren, indem wir den folgenden Code hinzufügen:

 const Visit = fordert ('Unist-util-vis-vit');

  module.exports = options => baum => {
    besuchen(
      Baum,
      // Besuchen Sie nur P -Tags, die ein IMG -Element enthalten
      node =>
        node.tagname === 'p' && node.children.some (n => n.tagname === 'img'),
      node => {
        console.log (Knoten);
      }
    );
};

Wenn wir dies ausführen, können wir sehen, dass nur ein Absatzknoten angemeldet ist:

 {
  Typ: 'Element',
  Tagname: 'P',
  Eigenschaften: {},
  Kinder: [
    {
      Typ: 'Element',
      Tagname: 'Img',
      Eigenschaften: [Objekt],
      Kinder: [],
      Position: [Objekt]
    },
    {Typ: 'Text', Wert: 'Ein entzückender Corgi!', Position: [Objekt]}
  ],
  Position: {
    Start: {Zeile: 3, Spalte: 1, Offset: 16},
    Ende: {Zeile: 3, Spalte: 102, Offset: 117}
  }
}

Perfekt! Wir erhalten nur den Absatzknoten, der das Bild hat, das wir ändern möchten. Jetzt können wir anfangen, das AST zu verwandeln!

(Siehe Diff)

Wickeln Sie das Bild in ein Figurenelement

Nachdem wir die Bildattribute haben, können wir beginnen, das AST zu ändern. Denken Sie daran, weil ASTS wirklich groß sein kann, mutieren wir sie an Ort und Stelle, um zu vermeiden, dass viele Kopien erzeugt werden und unser Drehbuch möglicherweise verlangsamt werden.

Wir beginnen damit, den TagNamen des Knotens zu einer Figur anstelle eines Absatzes zu ändern. Der Rest der Details kann vorerst gleich bleiben.

Nehmen Sie die folgenden Änderungen in SRC/IMG-to-Figure.js vor:

 const Visit = fordert ('Unist-util-vis-vit');

module.exports = options => baum => {
  besuchen(
    Baum,
    // Besuchen Sie nur P -Tags, die ein IMG -Element enthalten
    node =>
    node.tagname === 'p' && node.children.some (n => n.tagname === 'img'),
    node => {
      node.tagname = 'figure';
    }
  );
};

Wenn wir unser Skript wieder ausführen und uns die Ausgabe ansehen, können wir sehen, dass wir uns näher kommen!

 <h1 id="Hallo-Welt"> Hallo Welt! </h1>
<aby> <img src="<https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg>" alt="Cardigan Corgi"> ein entzückender Corgi! 
<p> Ein weiterer Text geht hier. </p></aby>

(Siehe Diff)

Verwenden Sie den Text neben dem Bild als Bildunterschrift

Um nicht die benutzerdefinierte Syntax schreiben zu müssen, verwenden wir einen beliebigen Text mit einem Bild als Bildunterschrift.

Wir können davon ausgehen, dass Bilder normalerweise keinen Inline -Text in Markdown haben, aber es ist erwähnenswert, dass dies zu 100% unbeabsichtigten Bildunterschriften für Personen erscheinen kann, die Markdown schreiben. Wir werden dieses Risiko in diesem Tutorial eingehen. Wenn Sie vorhaben, dies in Produktion zu bringen, achten Sie darauf, dass Sie die Kompromisse abwägen und wählen, was für Ihre Situation am besten ist.

Um den Text zu verwenden, suchen wir nach einem Textknoten innerhalb unseres übergeordneten Knotens. Wenn wir einen finden, wollen wir seinen Wert als unsere Bildunterschrift greifen. Wenn keine Bildunterschrift gefunden wird, wollen wir diesen Knoten überhaupt nicht verwandeln, damit wir früh zurückkehren können.

Nehmen Sie die folgenden Änderungen an SRC/IMG-to-Figure.js vor, um die Bildunterschrift zu ergreifen:

 const Visit = fordert ('Unist-util-vis-vit');

module.exports = options => baum => {
  besuchen(
    Baum,
    // Besuchen Sie nur P -Tags, die ein IMG -Element enthalten
    node =>
    node.tagname === 'p' && node.children.some (n => n.tagname === 'img'),
    node => {
      // den Textknoten finden
      const textNode = node.children.find (n => n.type === 'text');
 
      // Wenn es keine Bildunterschrift gibt, müssen wir den Knoten nicht transformieren
      if (! Texnode) return;
 
      const caption = TextNode.Value.trim ();
 
      console.log ({caption});
      node.tagname = 'figure';
    }
  );
};

Führen Sie das Skript aus und wir können die caption protokollierte sehen:

 {Bildunterschrift: 'Ein entzückender Corgi!' }

(Siehe Diff)

Fügen Sie der Abbildung ein Figcaption -Element hinzu

Nachdem wir unseren Bildunterschriftstext haben, können wir eine FigCaption hinzufügen, um sie anzuzeigen. Wir könnten dies tun, indem wir einen neuen Knoten erstellen und den alten Textknoten löschen, aber da wir an Ort und Stelle mutieren, ist es etwas weniger kompliziert, den Textknoten in ein Element zu ändern.

Elemente haben jedoch keinen Text, daher müssen wir einen neuen Textknoten als Kind des Figcaption -Elements hinzufügen, um den Bildunterschriftstext anzuzeigen.

Nehmen Sie die folgenden Änderungen an src/img-to-figure.js vor, um die Beschriftung zum Markup hinzuzufügen:

 const Visit = fordert ('Unist-util-vis-vit');

module.exports = options => baum => {
  besuchen(
    Baum,
    // Besuchen Sie nur P -Tags, die ein IMG -Element enthalten
    node =>
      node.tagname === 'p' && node.children.some (n => n.tagname === 'img'),
    node => {
      // den Textknoten finden
      const textNode = node.children.find (n => n.type === 'text');

      // Wenn es keine Bildunterschrift gibt, müssen wir den Knoten nicht transformieren
      if (! Texnode) return;

      const caption = TextNode.Value.trim ();
      // Ändern Sie den Textknoten in ein Figcaption -Element, das einen Textknoten enthält
      TextNode.Type = 'Element';
      TextNode.tagname = 'Figcaption';
      Textnode.Children = [
        {
          Typ: 'Text',
          Wert: Bildunterschrift
        }
      ];

      node.tagname = 'figure';
    }
  );
};

Wenn wir das Skript erneut mit Node SRC/Index.js ausführen, sehen wir das transformierte Bild, das in ein Figurenelement eingewickelt und mit einer Figcaption beschrieben wird!

 <h1 id="Hallo-Welt"> Hallo Welt! </h1>
<figure> <img src="<https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg>" alt="Cardigan Corgi"> <figcaption> Ein entzückender Corgi! <p> Ein weiterer Text geht hier. </p></figcaption></figure>

(Siehe Diff)

Speichern Sie den transformierten Inhalt in einer neuen Datei

Nachdem wir eine Reihe von Transformationen vorgenommen haben, möchten wir diese Anpassungen in einer tatsächlichen Datei speichern, damit wir sie teilen können.

Da der Markdown kein volles HTML-Dokument enthält, werden wir ein weiteres Rehype-Plugin namens Rehype-Dokument hinzufügen, um die vollständige Dokumentstruktur und ein Titel-Tag hinzuzufügen.

Installieren durch Ausführen:

 NPM Rehype-Dokument installieren

Nächst die folgenden Änderungen an SRC/INDEX.JS vornehmen:

 const fs = erfordern ('fs');
const Unified = fordert ('Unified');
const markdown = erfordern ('Bemerkung-Parse');
const merking2Rehype = fordert ('Bemerkenseiter');
const doc = fordert ('Rehype-Dokument');
const html = require ('rehype-stringify');

const imgtofigure = require ('./ img-to-figure');

const Inhalt = Unified ()
	.use (Markdown)
	.
	.use (imgtofigure)
    .use (doc, {title: 'ein transformiertes Dokument!'})
	.use (html)
	.ProcessSync (fs.readFilesync (`$ {process.cwd ()}/content/home.md`))
	.ToString ();

 const outputdir = `$ {process.cwd ()}/public`;

  if (! fs.existsSync (outputdir)) {
    fs.mkdirsync (outputdir);
  }
 
  fs.writeFilesync (`$ {outputDir}/home.html`, Inhalt);

Führen Sie das Skript erneut aus und wir können einen neuen Ordner in Root namens Public sehen, und im Inneren werden wir zu Hause sehen. Im Inneren wird unser transformiertes Dokument gespeichert!

  
<kopf>
<meta charset="utf-8">
<title> Ein transformiertes Dokument! </title>
<meta name="viewPort" content="width = Gerätebidth, initial-scale = 1">


	<h1 id="Hallo-Welt"> Hallo Welt! </h1>
	<figure> <img src="<https://images.dog.ceo/breeds/corgi-carder/n02113186_1030.jpg>" alt="Cardigan Corgi"> <figcaption> Ein entzückender Corgi! <p> Ein weiterer Text geht hier. </p>

</figcaption></figure></kopf>

Das obige ist der detaillierte Inhalt vonSo modifizieren Sie Knoten in einem abstrakten Syntaxbaum. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Zwei Bilder und eine API: alles, was wir für die Wiederbelebung von Produkten brauchenZwei Bilder und eine API: alles, was wir für die Wiederbelebung von Produkten brauchenApr 15, 2025 am 11:27 AM

Ich habe kürzlich eine Lösung gefunden, um die Farbe eines Produktbildes dynamisch zu aktualisieren. Mit nur einem Produkt können wir es auf unterschiedliche Weise zeigen, um zu zeigen

Wöchentliche Plattformnachrichten: Auswirkungen von Code von Drittanbietern, passive gemischte Inhalte, Länder mit den langsamsten VerbindungenWöchentliche Plattformnachrichten: Auswirkungen von Code von Drittanbietern, passive gemischte Inhalte, Länder mit den langsamsten VerbindungenApr 15, 2025 am 11:19 AM

In der Roundup in dieser Woche wird Lighthouse beleuchtet, die Drittanbieter-Skripte, unsichere Ressourcen auf sicheren Websites und viele Länderverbindungsgeschwindigkeiten blockiert werden

Optionen zum Hosting Ihrer eigenen nicht-javaScript-basierten AnalysenOptionen zum Hosting Ihrer eigenen nicht-javaScript-basierten AnalysenApr 15, 2025 am 11:09 AM

Es gibt eine Menge Analyseplattformen, mit denen Sie Besucher- und Nutzungsdaten auf Ihren Websites verfolgen können. Vielleicht vor allem Google Analytics, das weit verbreitet ist

Es ist alles in der KopfEs ist alles in der KopfApr 15, 2025 am 11:01 AM

Der Dokumentkopf ist vielleicht nicht der glamouröseste Teil einer Website, aber was darauf einfließt

Was ist Super () in JavaScript?Was ist Super () in JavaScript?Apr 15, 2025 am 10:59 AM

Was passiert, wenn Sie ein JavaScript sehen, das Super () aufruft. In einer Kinderklasse verwenden Sie Super (), um den Konstruktor und Super des Elternteils anzurufen. zugreifen

Vergleich der verschiedenen Arten von nativen JavaScript -PopupsVergleich der verschiedenen Arten von nativen JavaScript -PopupsApr 15, 2025 am 10:48 AM

JavaScript verfügt über eine Vielzahl von integrierten Popup-APIs, die eine spezielle Benutzeroberfläche für die Benutzerinteraktion anzeigen. Berühmt:

Warum sind zugängliche Websites so schwer zu erstellen?Warum sind zugängliche Websites so schwer zu erstellen?Apr 15, 2025 am 10:45 AM

Ich habe neulich mit einigen Front-End-Leuten darüber gesprochen, warum so viele Unternehmen zugängliche Websites erstellen. Warum sind Websites so schwer zugänglich?

Das `versteckte Attribut ist sichtlich schwachDas `versteckte Attribut ist sichtlich schwachApr 15, 2025 am 10:43 AM

Es gibt ein HTML -Attribut, das genau das tut, was Sie denken, dass es tun sollte:

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
1 Monate vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Herunterladen der Mac-Version des Atom-Editors

Herunterladen der Mac-Version des Atom-Editors

Der beliebteste Open-Source-Editor

VSCode Windows 64-Bit-Download

VSCode Windows 64-Bit-Download

Ein kostenloser und leistungsstarker IDE-Editor von Microsoft

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ist eine PHP/MySQL-Webanwendung, die sehr anfällig ist. Seine Hauptziele bestehen darin, Sicherheitsexperten dabei zu helfen, ihre Fähigkeiten und Tools in einem rechtlichen Umfeld zu testen, Webentwicklern dabei zu helfen, den Prozess der Sicherung von Webanwendungen besser zu verstehen, und Lehrern/Schülern dabei zu helfen, in einer Unterrichtsumgebung Webanwendungen zu lehren/lernen Sicherheit. Das Ziel von DVWA besteht darin, einige der häufigsten Web-Schwachstellen über eine einfache und unkomplizierte Benutzeroberfläche mit unterschiedlichen Schwierigkeitsgraden zu üben. Bitte beachten Sie, dass diese Software