9. Aufgabe ( Toolchen für Erstellung von Präsentationen )

Was früher ein Diavortrag ( Referat, Vortrag ) mit einem ( Tageslichtprojektor ) genannt wurde, war gestern noch eine "Fach-Termini-Rede" mit dem Overhead-Projektor und kann heute schon zu einem Mitmachen am eingenständigen Erstellen eines Erstellungstoolchens für Präsentationen werden. Insbesondere soll das das erstellte Toolchen klein und robust sein und auch für Blinde leicht bedienbar sein und ästetische "HTML-Power-Slides" erstellten

Jean de La Fontaine ( 1910-1995 ) sagt es so: "Man läuft Gefahr, zu verlieren, wenn man zu viel gewinnen möchte."

Kurzfassung der Aufgabe:

Es soll ein kleines, robustes Präsentation-Erstellungs-Toolchen entwickelt werden. Hier ist ein Muster für ein solches Erstellungs-Toolchen. Diese Toolchen-Entwicklung braucht hinreichendes Wissen zu Regulären Ausdrücken, deshalb ...

Reguläre Ausdrücke ( allgemein ) Was ist das?

Ausgangspunkt waren die Neurophysiologen Warren McCulloch und Walter Pitts, 1956 Stephen Kleene: "die Algebra regulärer Mengen", daher der Begriff: "regulärer Ausdruck". Ken Thompson (Unix) machte daraus die erste praktische Anwendung im Unix-Editor qed.

Reguläre Ausdrücke wurden zu einem unverzichtbaren Bestandteil von zeichenverarbeitenden Sytemen (z.B. textbasierten Editoren, Suchtools, XSLT, usw). Reguläre Ausdrücke können für Transformationen von Zeichenfolgen in modifizierte Zeichenfolgen (z.B.Suchen-und-Ersetzen) verwendet werden, siehe z.B. Reguläre Ausdrücke (Allgemeines, Spezielle Literalzeichen, Reguläre Ausdrücke und Funktionen bei ECMAScript, Referenz , Beispiele ).

Editor ( Suche/Ersetzen mit Regulären Ausdrücken ) Wie geht das?

Übung und Besprechung von "Suche/Ersetzen mit Regulären Ausdrücken bei einem Editor ( z.B. Notepad++ ) erfolgt in der Veranstaltung.

Mit Regulären Ausdrücken und ECMAScript wurde das ECMAScript-Toolchen erstellt, das dem Lernen und dem Umgang von Regulären Ausdrücken dienen kann. Hierzu bitte erst mit [bearbeiten] und dann [reguläre Audrücke] ein Zusatz-Menu einschalten.

Reguläre Ausdrücke und Template Wie ersetzen?

Ein String habe einen typischen Aufbau als HTML-Tabelle. Diese Tabelle soll an den markierten {key}-Stellen mit den repl_obj-Werten von repl_obj.key gefüllt werden. Wie kan dies mit Regulären Ausdrücker gemacht werden? Der Funktion templ_repl(templ_str, repl_obj) wird der templ_str und das repl_obj übergeben. Die Funktion templ_repl() liefert den "eingefüllten" String zurück. Bei einem Fehler findet an der entsprechenden Stelle keine Ersetzung statt.

 function templ_repl(templ_str, repl_obj) {
   return templ_str.replace(/\{([^{}]*)\}/g,
     function (a, b) { var r = repl_obj[b];
       return typeof r === 'string' ? r : a;
     });
 }
 var repl_obj = {
   vorname: "Hans Josef",
   nachname: "Weber"
 };
 var templ_str = '<h2>Anzeige</h2>' +
 '<table><tr><th>    Mein Nachname:</th><td>{nachname}' +
 '</td></tr><tr><th> Mein Vorname:</th><td>{vorname}' +
 '</td></tr></table>';

 document.getElementById("MYDIV").innerHTML = templ_repl(templ_str, repl_obj);
Toolchen-Entwicklungsanleitung Reihenfolge ...

Zum Erstellen eines Toolchen kann von einem Beispiel ausgegangen werden. Ziel ist es, die folgende Arbeitsansicht in eine HTML-Seite umzuwandel.

-titel; Meine Präsentation

-dia; Menu-Item1
-h3;  Erstellungstoolchen ( Wie ?)
-p;  Aus ASCII-Arbeitsansicht wird Praesentation ...
-p.r; Den Text eines p-Tags umrandet

- dia ; Menu-Item2
- h3 ; Ein weiteres Dia
- ta ;
  // -ta;
  if ( a < b ) { 
    ta = 15 > 2; 
  } 
-  p . r1 ;  -p.r1; Tag 
-  p . r1 blau ;  
   <em class="rot">-p.r1 blau;</em> Tag mit 2 css-Klassen
-  pre . r ;
   Das   -pre.r;  Tag 
     soll Blanks
       erhalten

Das Toolchen soll also eine HTML-Seite machen. Etwa:

{{ HTML-Header }}
<h1 class="titel"> Meine Präsentation</h1>

<form class="menu_form" action="#"> 
 <a class="menu_item" href="javascript:show_dia(1)"> Menu-Item1</a>
 <a class="menu_item" href="javascript:show_dia(2)"> Menu-Item2</a>
</form>


<form action="#" class=" show_form">
<h3> Erstellungstoolchen ( Wie ?) </h3>
<p> Aus ASCII-Arbeitsansicht wird Praesentation ...</p>
<p class="r"> Den Text eines p-Tags umrandet </p>
</form>


<form action="#" class=" hide_form">
<h3> Ein weiteres Dia </h3>
<textarea cols="90" rows="5" tabindex="0"> // -ta;
  if ( a < b ) { 
    ta = 15 > 2; 
  }</textarea>

<p class=" r1"> -p.r1; Tag </p>
<p class=" r1 blau">
   <em class="rot">-p.r1 blau;</em> Tag mit 2 css-Klassen
</p>
<pre class=" r" tabindex="0"> 
   Das   -pre.r;  Tag 
     soll Blanks
       erhalten
</pre>
</form>
{{ HTML-Ende }}
Grundgerüst für das Toolchen 1. Schritt

Warum werden form-Tags verwendet? Eine Textarea kann ohne Umwandlung direkt HTML-, JavaScript-, C-Code aufnehmen. Eine Textarea braucht ein umschließendes form-Tag.

Wie gehen wir vor? Hier ist ein Grundgerüst für das Toolchen Als Ausgangspunkt werden lediglich bekannte Funktionen verwendet. Es wird "seitenglobal" mit ECMAScript gearbeitet. Das Grundgerüst wird systematisch erweitert und jeder Schritt getestet.

Zerlege die Arbeitsansicht in Token und Content 2. Schritt

Zum einfachen Testen kann die Fehlerkonsole des Browsers verwendet werden. Als Hilfsfunktion während der Entwicklung kann die debug_ausgabe(id_dst, arr, hinweis_zur_ausgabe) Array-Content in der Textarea anzeigen ( siehe /*1*/ ). Bei /*2*/ werden die verwendeten Array's deklariert und kommentiert.

Damit der reguläre Ausdruck

src = src.replace(/\r?\n\s*\-\s*([^\s]*)\s*(\.\s*[\S\s]*?)?\s*;/g, 'C_HLP$1$2C_HLP');

auch bereits die 0.src-Zeile (die keine \n haben muß) erfaßt, wurde vor den dem Anfang von src ein \n eingefügt, etwa

  src = '\n' + src;         // zusätzliches \n am Anfang der Arbeitsansicht
  src += '\n-ENDE_KENNUNG'; // zusätzlichen Leer-Token am Ende der Arbeitsansicht

Bitte bei /*3*/ das erste Element aus dem split-Array entfernen ( etwa mit split.shift(); ).

// Jetzt sollte der split-Array enthalten: 
// split[i]    das              tagName.className-Token enthalten
// split[i+1]  den Text-Content tagName.className-Token enthalten
// Eine Testanzeige von slit-Array ist möglich mit:
   debug_ausgabe(id_dst, split, "Token-Kontrolle" );return;
Wandle split[ ] in cmd[ ], cls[ ], text[ ] 3. Schritt

Die Schleife bei [*4*] soll split[ ] in 2-er steps durchlaufen, weil
split[i] das cmd- und cls-Token enthält, d.h. jedes split[i] besteht aus t[0] = tagName und t[1] = className's und
split[i+1] den Text-Content zum cmd-Token enthält.

Die Zählvariable j sorgt dafür, daß cmd[ ], cls[ ], text[ ] in "Einer-Steps" geschrieben werden.

[*4*]
  j = -1; // Wandle split[ ] in cmd[ ], cls[ ], text[ ]
  for (i = 0; i < split.length - 1; i += 2) {
    j += 1;
    // t[i] = tagName, t[i+1] = className's 
    text[j] = split[i + 1];  t = split[i].split('.');
    cmd[j] = t[0]; 
    cls[j] = ''; if (t[1]) { cls[j] = t[1]; } //' class="' + t[1]+'"'; }
  }

Wie wird die die Endekennung "-ENDE_KENNUNG" aus dem letzten text[ ] Element gelöscht?

Wie wird die Schleife bei [*4*] danach getestet?

// Teste cmd[ ], cls[ ], text[ ] nach [*4*] 

// Testanzeige vom cmd-Array:
   debug_ausgabe(id_dst, cmd, "cmd-Kontrolle" );return;

// Testanzeige von cls-Array:
// debug_ausgabe(id_dst, cls, "cls-Kontrolle" );return;

// Testanzeige von text-Array:
// debug_ausgabe(id_dst, text, "text-Kontrolle" );return;
Mach aus cmd[ ], cls[ ], text[ ] nun HTML 4. Schritt

Wie können nun die getesteten Array's cmd[ ], cls[ ], text[ ] zu einer HTML5-Seite zusammen gesetzt werden?

In einer cmd[ ]-Schleife werden alle "tagName"-Token durchlaufen. Jedes cmd[ ]-Token macht einen HTML5-push-Eintrag in den dia[ ]-Array. Speziell beim dia-Token wird zusätzlich ein a-Tag-Eintrag in den menu[ ]-Array gemacht. Alle Elemente von menu[ ] ergeben form[0]. Jedes dia[i] gehört zu form[i] mit i > 0.

switch (cmd[i]) { ... } behandelt die "tagName"-Token.

  dia_nr = 0; // dia_nr wird bei einem -dia;-Token hochgezählt.
  for (i = 0; i < cmd.length; i += 1) {
    txt = text[i].replace(/^\s+|\s+$/g, ''); // txt = trim text[i]
    cls_str = ''; if (cls[i] !== '') { cls_str = ' class="' + cls[i] + '"'; }

    switch (cmd[i]) {
    case 'titel': titel = txt; break;
/*
    case 'dia': dia_nr += 1; // -dia wird zu form-Tag
      // Jedes dia-Token macht einen zusätzlichen Eintrag in den form[0] menu-Array

      if (dia_nr === 1) { menu.push('\n<form class="menu_form" action="#"> '); }
      if (txt === '') { txt = 1 + dia_nr; }
      menu.push(' <a class="menu_item" href="javascript:show_dia(' + (dia_nr) + ')"> ' + txt + '</a>\n');

      // bei onload nur erste html-form sichtbar mit 'show_form' sichtbar machen
      t = cls_str + ' hide_form';
      if (dia_nr === 1) { t = cls_str + ' show_form'; }
      t = '<\/form>\n\n\n<form action="#" class="' + t + '">';
      dias.push(t);
    break;

    case 'pre': // Das pre-Tag soll Blanks erhaltend sein
      //dias.push('<' + cmd[i] + cls_str + ... + '\n<\/' + cmd[i] + '>');
    break;

    case 'ta': t = txt.split('\n').length + 1;
      //dias.push('<textarea cols="90" rows="' + t + '"' + ... + '<\/textarea>');
    break;
*/

    default: // hierher kommen alle cmd[i], die keine Sonderbehandlung haben:
      t = ''; if (cls[i] !== '') { t = ' class="' + cls[i] + '"'; }
      dias.push('\n<' + cmd[i] + cls_str + '>\n' + txt + '\n<\/' + cmd[i] + '>');
    break;
  } // ende switch
} // ende for
Teste den String menu.join('\n') + dias.join('\n') 5. Schritt

Nach "ende for" kommt ein schließender dias.push('<\/form>'); Wie sieht dann ein Test für menu[ ], dias[ ] und
titel + menu.join('\n') + dias.join('\n') aus?

// [*5*] Teste menu[ ], dia[ ] und  menu.join('\n')+dias.join('\n')
   debug_ausgabe(id_dst, menu, "Menu-Kontrolle" );return;
// debug_ausgabe(id_dst, dias, "Dias-Kontrolle" );return;
// debug_ausgabe(id_dst, titel+menu.join('\n')+dias.join('\n'), "titel+nemu+dias-Kontrolle" );return;
HTML5-Probe-Funktionalität 6. Schritt

Wenn alle Tests OK sind, so kann von Hand (am HTML-Anfang) ein Style und die ECMAScript-Funktion show_dia(dia_nr) eingefügt werden. Die Vorschau zeigt die Funktionalität.

<style>
form.hide_form {position: absolute;top:auto;left:-9999px;overflow:hidden;}
form.show_form {position:relative;top:auto;left:auto;overflow:auto;}
</style>
<script>
function show_dia(dia_nr) {  var i, f = document.forms;
  for (i = 1; i < f.length; i += 1) { f[i].className = 'hide_form'; }
  f[dia_nr].className='show_form';
}
</script>
"Perfekter Feinschliff" 7. Schritt

Ähnlich wie die vorhanden Variable html_end können auch der gesamte HTML-Head incl. Style und script ( aus 6 ) "escaped" und auf html_start = "..."; gesetzt werden. Im Code bereits vorhanden sind

// [*7a*] siehe ganz oben
html_end = "%3C/body%3E%0A%3C/html%3E%0A",
html_start = "...";

Die obige (einfache Funktion show_dia(dia_nr) {...} reicht. Der bisherige einfache Style der Präsentation kann perfektioniert werden (siehe etwa verbesserter Präsentationsstyle )

html_start enthalte den gesamten HTML5-head, incl.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex" />
<title> T_I_T_E_L </title>
<style> ... </style>
<script> ... </script>
</head>
<body> 

und sei in einen escape-%-String gewandelt. Dann kann bei //[*7*] eingefügt werden:

//[*7*]
t = window.unescape(html_start);
t = t.replace("T_I_T_E_L", titel);
t += '<h1 class="titel"> ' + titel + '</h1>\n';
src = menu.join('\n') + dias.join('\n') + window.unescape(html_end);
src = src.replace(/oA_HLP/g, '-'); // zurück-ersetzen, falls in ta am Zeilenanfang \-g; 
set_string(id_dst, t + src);
Was ist noch zu tun? 8. Schritt

Perfektion ist ein Ideal und als solches unerreichbar. Dennoch sollte ...

Viel Freude bei der Ausarbeitung!
Letzter Abgabetermine So 12.00 Uhr