#20 Skriptování: výstupní formáty: text (prostý), xhtml (fragment), xml (celý dokument, může mít XML deklaraci).
authorFrantišek Kučera <franta-hg@frantovo.cz>
Thu, 05 Jul 2012 20:13:56 +0200
changeset 108 8d9cab64c335
parent 107 379a2a893fd1
child 109 f9e3ee9cc924
#20 Skriptování: výstupní formáty: text (prostý), xhtml (fragment), xml (celý dokument, může mít XML deklaraci).
vstup/makra/hg-verze.xsl
vstup/skriptování.xml
šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java
šablona/makra/skriptování.xsl
--- a/vstup/makra/hg-verze.xsl	Thu Jul 05 19:10:42 2012 +0200
+++ b/vstup/makra/hg-verze.xsl	Thu Jul 05 20:13:56 2012 +0200
@@ -10,24 +10,12 @@
 	xmlns:svg="http://www.w3.org/2000/svg"
 	xmlns:xs="http://www.w3.org/2001/XMLSchema"
 	exclude-result-prefixes="fn h s k m xs">
-
+	
 	<!-- Vypíše verze z verzovacího systému: -->
 	<xsl:template match="m:hg-verze">
+
 		<xsl:variable name="zadáníSkriptu">
-			<!--
-				TODO:
-				Zahazovat XML deklaraci bychom mohli v Javě u všech skriptů… 
-				Nicméně současná dohoda je taková, že skripty vracejí fragment, ne celý dokument,
-				což má výhodu v tom, že můžou vrátit kus textu a nějakou tu značku
-				a nemusí to být zabalené v kořenovém elementu.
-				
-			-->
-			<m:skript jazyk="bash" výstup="xml">hg log --style xml | awk '{if(NR&gt;1)print}';</m:skript>
-			<!--
-				Také bychom filtrování mohli provés ve skriptu…
-				hg log … | xpath -e "//logentry[tag[starts-with(., 'v')]]" 2>/dev/null
-				 …ale to by bylo trochu zbytečně pracné.
-			-->
+			<m:skript jazyk="bash" výstup="xml">hg log --style xml</m:skript>
 		</xsl:variable>
 
 		<xsl:variable name="výstupSkriptu">
@@ -42,10 +30,6 @@
 				</tr>
 			</thead>
 			<tbody style="text-align: right;">
-				<!--
-					Výstup skriptu se bude nacházet v XHTML jmenném prostoru, což je obvykle v pořádku,
-					ale pro mezivýsledky to není úplně vhodné.
-				-->
 				<xsl:for-each select="$výstupSkriptu/h:log/h:logentry[h:tag[starts-with(text(), 'v')]]">
 					<tr>
 						<td><xsl:value-of select="substring(h:tag/text(), 2)"/></td>
--- a/vstup/skriptování.xml	Thu Jul 05 19:10:42 2012 +0200
+++ b/vstup/skriptování.xml	Thu Jul 05 20:13:56 2012 +0200
@@ -6,7 +6,7 @@
 	<pořadí>50</pořadí>
 
 	<text xmlns="http://www.w3.org/1999/xhtml">
-	
+
 		<p>
 			Na stránkách můžeme používat skripty.
 			Spouští se při generování a jejich standardní výstup se vloží do stránky.
@@ -40,7 +40,7 @@
 		<p>
 			V současnosti jsou podporované tyto jazyky:
 		</p>
-		
+
 		<table>
 			<thead>
 				<tr>
@@ -49,7 +49,7 @@
 				</tr>
 			</thead>
 			<tbody>
-				<m:skript jazyk="perl" výstup="xml"><![CDATA[
+				<m:skript jazyk="perl" výstup="xhtml"><![CDATA[
 use strict;
 use warnings;
 
@@ -111,7 +111,7 @@
 			<p>
 				Ve skriptech máme dostupné následující proměnné prostředí:
 			</p>
-			
+
 			<table>
 				<thead>
 					<tr>
@@ -121,23 +121,23 @@
 				</thead>
 				<tbody>
 					<!-- Pokud načítáme skript ze souboru, je atribut jazyk nepovinný. -->
-					<m:skript jazyk="perl" výstup="xml" src="skriptování-proměnné.pl"/>
+					<m:skript jazyk="perl" výstup="xhtml" src="skriptování-proměnné.pl"/>
 				</tbody>
 			</table>
-			
+
 			<p>
 				Kód:
 			</p>
-			
+
 			<m:pre jazyk="xml"><![CDATA[<m:skript jazyk="bash">
 echo "URI:    $XWG_STRANKA_URI";
 echo "Soubor: $XWG_STRANKA_SOUBOR";
 echo "Nadpis: $XWG_STRANKA_NADPIS";
 echo "Perex:  $XWG_STRANKA_PEREX";
 </m:skript>]]></m:pre>
-			
+
 			<p>nám vypíše:</p>
-			
+
 			<pre><m:skript jazyk="bash"><![CDATA[
 echo "URI:    $XWG_STRANKA_URI" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
 echo "Soubor: $XWG_STRANKA_SOUBOR" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
@@ -148,7 +148,7 @@
 		<h2>Makra ve skriptech</h2>
 		<p>
 			XML generované skriptem může také obsahovat makra, která se následně interptetují.
-			<m:skript jazyk="bash" výstup="xml"><![CDATA[
+			<m:skript jazyk="bash" výstup="xhtml"><![CDATA[
 echo '<m:skript jazyk="bash">'; # Ty zrůdo! :-)
 echo 'echo "Takže můžeš skriptovat, když skriptuješ,";';
 echo '</m:skript>';
@@ -156,7 +156,7 @@
 			nebo dělat něco užitečnějšího.
 		</p>
 		
-		<m:skript jazyk="perl" výstup="xml"><![CDATA[
+		<m:skript jazyk="perl" výstup="xhtml"><![CDATA[
 use strict;
 use warnings;
 
@@ -179,9 +179,9 @@
 print "</m:diagram>";
 closedir(DIR);
 		]]></m:skript>
-		
+
 		<p>…třeba vygenerovat tento diagram následujícím perlovským skriptem:</p>
-		
+
 		<m:pre jazyk="perl"><![CDATA[
 use strict;
 use warnings;
@@ -206,7 +206,7 @@
 closedir(DIR);]]></m:pre>
 
 		<p>
-			Který vložíme zabalený v <code><![CDATA[<m:skript jazyk="perl" výstup="xml"> … </m:skript>]]></code> do stránky.
+			Který vložíme zabalený v <code><![CDATA[<m:skript jazyk="perl" výstup="xhtml"> … </m:skript>]]></code> do stránky.
 		</p>
 		<p>
 			Známá chyba: ve skriptech zatím nefungují poznámky pod čarou (a není jisté, jestli kdy fungovat budou – pravděpodobně by to vyžadovalo vícefázové zpracování).
--- a/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java	Thu Jul 05 19:10:42 2012 +0200
+++ b/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java	Thu Jul 05 20:13:56 2012 +0200
@@ -40,6 +40,12 @@
  */
 public class Skriptování {
 
+	private enum FORMÁT {
+
+		xml,
+		xhtml,
+		text
+	}
 	/**
 	 * klíč = jazyk – např. bash
 	 * hodnota = interpret – např. /bin/bash
@@ -70,7 +76,7 @@
 	 */
 	public static Source interpretuj(String skriptText, String skriptSoubor, String jazyk, String výstupníFormát, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
 		String výstupSkriptu = získejVýstupSkriptu(skriptText, skriptSoubor, jazyk, uriStránky, nadpisStránky, perexStránky);
-		return vyrobXml(výstupSkriptu, "xml".equals(výstupníFormát));
+		return vyrobXml(výstupSkriptu, zjistiFormát(výstupníFormát));
 	}
 
 	private static String získejVýstupSkriptu(String skriptText, String skriptSoubor, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) throws Exception {
@@ -169,26 +175,29 @@
 		return !(s == null || s.trim().isEmpty());
 	}
 
+	private static FORMÁT zjistiFormát(String výstupníFormát) {
+		try {
+			return FORMÁT.valueOf(výstupníFormát);
+		} catch (NullPointerException e) {
+			return FORMÁT.text;
+		} catch (IllegalArgumentException e) {
+			return FORMÁT.text;
+		}
+	}
+
 	/**
 	 * @param zadání výstup vygenerovaný skriptem
 	 * @param xmlFormát formát zadání: true = xml fragment | false = prostý text
 	 * @return xml fragment nebo prostý text zabalený do html/body
 	 * @throws Exception
 	 */
-	private static Source vyrobXml(String zadání, boolean xmlFormát) throws Exception {
+	private static Source vyrobXml(String zadání, FORMÁT formát) throws Exception {
 		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 		DocumentBuilder db = dbf.newDocumentBuilder();
 		Document d;
 
-		if (xmlFormát) {
-			try {
-				zadání = "<html xmlns='" + XHTML + "' xmlns:m='" + MAKRO + "'><body>" + zadání + "</body></html>";
-				d = db.parse(new ByteArrayInputStream(zadání.getBytes()));
-			} catch (Exception e) {
-				System.err.println("Chyba: Skript vrátil neplatné XML.");
-				throw e;
-			}
-		} else {
+
+		if (formát == FORMÁT.text) {
 			d = db.newDocument();
 			Node html = d.createElementNS(XHTML, "html");
 			Node body = d.createElementNS(XHTML, "body");
@@ -196,6 +205,16 @@
 			body.appendChild(text);
 			html.appendChild(body);
 			d.appendChild(html);
+		} else {
+			if (formát == FORMÁT.xhtml) {
+				zadání = "<html xmlns='" + XHTML + "' xmlns:m='" + MAKRO + "'><body>" + zadání + "</body></html>";
+			}
+			try {
+				d = db.parse(new ByteArrayInputStream(zadání.getBytes()));
+			} catch (Exception e) {
+				System.err.println("Chyba: Skript vrátil neplatné XML.");
+				throw e;
+			}
 		}
 
 		return new DOMSource(d);
--- a/šablona/makra/skriptování.xsl	Thu Jul 05 19:10:42 2012 +0200
+++ b/šablona/makra/skriptování.xsl	Thu Jul 05 20:13:56 2012 +0200
@@ -32,7 +32,10 @@
 		Provedeme skript zadaný v těle elementu nebo v souboru a jeho výstup vložíme do stránky.
 		*
 		@jazyk programovací jazyk, např. bash, perl, php (nepovinné, pokud je vyplněn atribut src)
-		@výstup formát výstupu skriptu: text (výchozí) | xml (musí být validním fragmentem XML)
+		@výstup formát výstupu skriptu:
+			text – libovolný text, escapujeme (výchozí)
+			xhtml – platný XML fragment, přidáme mu výchozí jmenný prostor XHTML a jmenný prostor pro makra
+			xml – platný XML dokument – vhodné pro další zpracování v jiných makrech
 		@src soubor se skriptem/programem (volitelný parametr – buď zadáme skript do těla elementu, nebo nastavíme tento atribut)
 	-->
 	<xsl:template match="m:skript">
@@ -50,7 +53,16 @@
 																	//s:stránka/s:nadpis/text(),
 																	//s:stránka/s:perex/text()
 																)"/>
-				<xsl:apply-templates select="$výstupSkriptu/h:html/h:body/node()"/>
+				<xsl:choose>
+					<xsl:when test="@výstup = 'xml'">
+						<!-- XML výstup zpracujeme, jak je: -->
+						<xsl:apply-templates select="$výstupSkriptu/*"/>
+					</xsl:when>
+					<xsl:otherwise>
+						<!-- Prostý text a XHTML fragmenty dostáváme zabalené v html/body -->
+						<xsl:apply-templates select="$výstupSkriptu/h:html/h:body/node()"/>
+					</xsl:otherwise>
+				</xsl:choose>
 			</xsl:when>
 
 			<xsl:when test="$režim = 'zakázat'">
@@ -59,7 +71,7 @@
 			<xsl:when test="$režim = 'ignorovat'">
 				<xsl:message>Stránka obsahuje skripty, ale skripty jsou ignorovány – změnu lze provést ve web.conf.</xsl:message>
 			</xsl:when>
-			<xsl:when test="$režim = 'vložit' and @výstup = 'xml'">
+			<xsl:when test="$režim = 'vložit' and (@výstup = 'xml' or @výstup = 'xhtml')">
 				<xsl:message>Není možné jen tak vložit text, který měl mít výstup ve formátu XML – změnu lze provést ve web.conf</xsl:message>
 			</xsl:when>
 			<xsl:when test="$režim = 'vložit'">
@@ -69,7 +81,7 @@
 			</xsl:when>
 			<xsl:otherwise><!-- varovat = výchozí možnost -->
 				<xsl:choose>
-					<xsl:when test="@výstup = 'xml'">
+					<xsl:when test="@výstup = 'xml' or @výstup = 'xhtml'">
 						<xsl:message>Není možné možné vložit varování na místo, kde měl být skript generující XML – změnu lze provést ve web.conf</xsl:message>
 					</xsl:when>
 					<xsl:otherwise>