Klammerpaare hervorheben

Gumbo

Erfahrenes Mitglied
Hallo,

ich suche einen Algorithmus, mit dem zusammengehörige Klammernpaare einer Quellcodedarstellung hervorgehoben werden.


Dazu habe ich erst einmal alle Klammen mit entsprechenden Elementen und Klassen (<span class="brace">x</span>) ausgezeichnet.

Nachfolgende JavaScript-Funktion soll nun die zusammengehörigen Klammernpaare hervorheben. Teilweise funktioniert es auch bereits – jedoch nur teilweise.
Code:
function init() {
	var allowedBrackets = new Array(
		new Array("(", ")"),
		new Array("{", "}"),
		new Array("[", "]")
	);
	var brackets = new Array();
	var brackets_count = new Array(1, 1, 1);
	var bracket_className = "brace";
	var bracket_className_hover = "brace-hover";
	var spanElements = document.getElementsByTagName("span");

	for(var i=0; i<spanElements.length; i++) {
		if( spanElements[i].getAttribute("class").indexOf("brace") < 0 ) {
			continue;
		}
		brackets.push(spanElements[i]);
	}
	for(i=0; i<brackets.length; i++) {
		for(var j=0; j<allowedBrackets.length; j++) {
			if( allowedBrackets[j][0] == brackets[i].firstChild.nodeValue ) {
				brackets[i].setAttribute("id", "bracket-" + j + "-" + brackets_count[j] + "-open");
				brackets[i].onmouseover = new Function("this.className='" + bracket_className_hover + "'; document.getElementById('bracket-" + j + "-" + brackets_count[j] + "-close').className='" + bracket_className_hover + "'");
				brackets[i].onmouseout = new Function("this.className='" + bracket_className + "'; document.getElementById('bracket-" + j + "-" + brackets_count[j] + "-close').className='" + bracket_className + "'");
				brackets_count[j]++;
			}
			if( allowedBrackets[j][1] == brackets[i].firstChild.nodeValue ) {
				brackets_count[j]--;
				brackets[i].setAttribute("id", "bracket-" + j + "-" + brackets_count[j] + "-close");
				brackets[i].onmouseover = new Function("this.className='" + bracket_className_hover + "'; document.getElementById('bracket-" + j + "-" + brackets_count[j] + "-open').className='" + bracket_className_hover + "'");
				brackets[i].onmouseout = new Function("this.className='" + bracket_className + "'; document.getElementById('bracket-" + j + "-" + brackets_count[j] + "-open').className='" + bracket_className + "'");
			}
		}
	}

}
Dazu noch ein passendes Testobjekt:
HTML:
<pre>if<span class="brace">(</span> isset<span class="brace">(</span>$bla<span class="brace">[</span>0<span class="brace">]</span><span class="brace">)</span> <span class="brace">)</span> <span class="brace">{</span>
	echo dummy<span class="brace">(</span>$bla<span class="brace">)</span>;
<span class="brace">}</span></pre>

Ich hoffe, dieses Thema ist nicht zu kompliziert für euch und jemand kann mir einen guten Ratschlag geben.
 
Hi,

mit deiner Auszeichnung werden keine eindeutigen IDs in den SPAN-Tags erzeugt. So hätten
im folgenden Beispiel beide öffnenden Klammern die gleiche ID:

Beispiel: ()()
Erste und zweite öffnende Klammern hätten die ID bracket-0-1-open. Deshalb auch die
Fehldarstellungen.

Versuche mal folgende Variante:
Code:
function init() {
  var allowedBrackets = new Array(
    new Array("(", ")"),
    new Array("{", "}"),
    new Array("[", "]")
  );
  var brackets = new Array();
  var bracket_className = "brace";
  var bracket_className_hover = "brace-hover";
  var spanElements = document.getElementsByTagName("span");

  // Hilfsvariable für eindeutige ID
  var intHelp = 0;
  // Array, das in der letzten Komponente immer die Nummer (intHelp)
  // der zuletzt geöffneten Klammer enthält
  var arrMemBrackets = new Array();

  for(var i=0; i<spanElements.length; i++) {
    //
    //if( spanElements[i].getAttribute("class").indexOf("brace") < 0 ) {
    if( spanElements[i].className.indexOf("brace") < 0 ) {
      continue;
    }
    brackets.push(spanElements[i]);
  }

  for(i=0; i<brackets.length; i++) {
    for(var j=0; j<allowedBrackets.length; j++) {
      if( allowedBrackets[j][0] == brackets[i].firstChild.nodeValue ) {
        arrMemBrackets.push(intHelp);
        intHelp++;
        brackets[i].setAttribute("id", "bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-open");
        brackets[i].onmouseover = new Function("this.className='" + bracket_className_hover + "'; document.getElementById('bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-close').className='" + bracket_className_hover + "';");
        brackets[i].onmouseout = new Function("this.className='" + bracket_className + "'; document.getElementById('bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-close').className='" + bracket_className + "'");
      }
      if( allowedBrackets[j][1] == brackets[i].firstChild.nodeValue ) {
        brackets[i].setAttribute("id", "bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-close");
        brackets[i].onmouseover = new Function("this.className='" + bracket_className_hover + "'; document.getElementById('bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-open').className='" + bracket_className_hover + "'");
        brackets[i].onmouseout = new Function("this.className='" + bracket_className + "'; document.getElementById('bracket-" + j + "-" + arrMemBrackets[arrMemBrackets.length - 1] + "-open').className='" + bracket_className + "'");
          arrMemBrackets.pop();
      }
    }
  }
}
Die Variable intHelp wird mit jeder geöffneten Klammer inkrementiert und ihr Wert in
die letzte Komponente eines "Speicher-Arrays" eingetragen. Soll ein Klammerpaar geschlossen
werden, so wird seine Nummer aus dem Array gelesen und die Komponente entfernt.

Ciao
Quaese
 
Vielen Dank, Quaese, es funktioniert ausgezeichnet!

Du hast mir eine Menge Kopfzerbrechen abgenommen.


Falls dich das Ergebis interessiert …
 
Ich hab nun die Funktionalität etwas erweitert. So ist es nun möglich zum Gegenstück einer eckigen Klammer zu springen. Auch die anderen Klammern einzubeziehen, hielt ich für nicht sinnvoll.
 

Neue Beiträge

Zurück