Skriptování: první verze
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 23 Jun 2012 18:00:41 +0200
changeset 944b3ba32f613c
parent 93 5b55827de220
child 95 eea9c4713045
Skriptování: první verze
vstup/skriptování.xml
šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java
šablona/makra/skriptování.xsl
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/vstup/skriptování.xml	Sat Jun 23 18:00:41 2012 +0200
     1.3 @@ -0,0 +1,109 @@
     1.4 +<stránka
     1.5 +	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
     1.6 +	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
     1.7 +	<nadpis>Skriptování</nadpis>
     1.8 +	<perex>Na stránku můžeme vložit výstup skriptů.</perex>
     1.9 +
    1.10 +	<text xmlns="http://www.w3.org/1999/xhtml">
    1.11 +	
    1.12 +		<p>
    1.13 +			Na stránkách můžeme používat skripty.
    1.14 +			Spouští se při generování a jejich standardní výstup se vloží do stránky.
    1.15 +			Třeba doprostřed ostavce nebo do jiného elementu.
    1.16 +		</p>
    1.17 +		<p>
    1.18 +			Příklad:
    1.19 +			Tyto stránky byly vygenerované v systému <m:skript jazyk="bash">uname -o</m:skript>.
    1.20 +		</p>
    1.21 +		
    1.22 +		<p>
    1.23 +			V současnosti jsou podporované tyto jazyky:
    1.24 +		</p>
    1.25 +		
    1.26 +		<pre><m:skript jazyk="perl"><![CDATA[
    1.27 +use strict;
    1.28 +
    1.29 +open(JAVA, "<", "šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java") or die $!;
    1.30 +
    1.31 +while (<JAVA>) {
    1.32 +#i.put("bash", "/bin/bash");
    1.33 +	if (/podporovanýJazyk\.put\("(\w+)",\s*"(.*)"\);/) {
    1.34 +		print "$1\n";
    1.35 +	}
    1.36 +}
    1.37 +			]]></m:skript></pre>
    1.38 +
    1.39 +		<h2>Perl</h2>
    1.40 +		<p>Jazyky použité nebo citované na této stránce:</p>
    1.41 +		<pre><m:skript jazyk="perl"><![CDATA[
    1.42 +use strict;
    1.43 +
    1.44 +open(XML, "<", $ENV{"XWG_STRANKA_SOUBOR"});
    1.45 +my %skripty;
    1.46 +
    1.47 +while (<XML>) {
    1.48 +	if (/m:skript\s+jazyk="(\w+)"/) {
    1.49 +		$skripty{$1}++;
    1.50 +	}
    1.51 +}
    1.52 +
    1.53 +for(keys(%skripty)) {
    1.54 +	print "$skripty{$_}×\t $_\n";
    1.55 +}
    1.56 +			]]></m:skript></pre>
    1.57 +
    1.58 +			<h2>BASH</h2>
    1.59 +		<pre><m:skript jazyk="bash"><![CDATA[
    1.60 +echo -n "Právě je: ";
    1.61 +date;
    1.62 +echo -n "Operační systém: ";
    1.63 +uname -sir;
    1.64 +echo -n "SHA-1 otisk zdrojáku této stránky: ";
    1.65 +sha1sum < $XWG_STRANKA_SOUBOR;
    1.66 +			]]></m:skript></pre>
    1.67 +
    1.68 +			<!--
    1.69 +			<h2>PHP</h2>
    1.70 +			<pre style="max-height: 200px;"><m:skript jazyk="php"><![CDATA[
    1.71 +<?php
    1.72 +phpinfo();
    1.73 +?>
    1.74 +			]]></m:skript></pre>
    1.75 +			-->
    1.76 +
    1.77 +			<h2>Proměnné prostředí</h2>
    1.78 +			<p>
    1.79 +				Ve skriptech máme dostupné následující proměnné prostředí:
    1.80 +			</p>
    1.81 +			
    1.82 +			<ul>
    1.83 +				<li><code>XWG_STRANKA_URI</code> – URI aktuálně zpracovávané stránky</li>
    1.84 +				<li><code>XWG_STRANKA_SOUBOR</code> – absolutní cesta k souboru</li>
    1.85 +				<li><code>XWG_STRANKA_NADPIS</code> – nadpis stránky</li>
    1.86 +				<li><code>XWG_STRANKA_PEREX</code> – perex stránky</li>
    1.87 +			</ul>
    1.88 +			
    1.89 +			<p>
    1.90 +				Kód:
    1.91 +			</p>
    1.92 +			
    1.93 +			<m:pre jazyk="xml"><![CDATA[<m:skript jazyk="bash">
    1.94 +echo "URI:    $XWG_STRANKA_URI";
    1.95 +echo "Soubor: $XWG_STRANKA_SOUBOR";
    1.96 +echo "Nadpis: $XWG_STRANKA_NADPIS";
    1.97 +echo "Perex:  $XWG_STRANKA_PEREX";
    1.98 +</m:skript>]]></m:pre>
    1.99 +			
   1.100 +			<p>nám vypíše:</p>
   1.101 +			
   1.102 +			<pre><m:skript jazyk="bash"><![CDATA[
   1.103 +echo "URI:    $XWG_STRANKA_URI" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
   1.104 +echo "Soubor: $XWG_STRANKA_SOUBOR" | sed s/\\/home\\/$USER/\\/home\\/xwg/g;
   1.105 +echo "Nadpis: $XWG_STRANKA_NADPIS";
   1.106 +echo "Perex:  $XWG_STRANKA_PEREX";
   1.107 +		]]></m:skript></pre>
   1.108 +
   1.109 +	</text>
   1.110 +
   1.111 +</stránka>
   1.112 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/šablona/funkce/src/cz/frantovo/xmlWebGenerator/makra/Skriptování.java	Sat Jun 23 18:00:41 2012 +0200
     2.3 @@ -0,0 +1,131 @@
     2.4 +/**
     2.5 + * XML Web generátor – program na generování webových stránek
     2.6 + * Copyright © 2012 František Kučera (frantovo.cz)
     2.7 + *
     2.8 + * This program is free software: you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License as published by
    2.10 + * the Free Software Foundation, either version 3 of the License, or
    2.11 + * (at your option) any later version.
    2.12 + *
    2.13 + * This program is distributed in the hope that it will be useful,
    2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    2.16 + * GNU General Public License for more details.
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License
    2.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    2.20 + */
    2.21 +package cz.frantovo.xmlWebGenerator.makra;
    2.22 +
    2.23 +import static cz.frantovo.xmlWebGenerator.NástrojeCLI.načtiProud;
    2.24 +import java.io.File;
    2.25 +import java.io.PrintStream;
    2.26 +import java.net.URI;
    2.27 +import java.util.Collections;
    2.28 +import java.util.HashMap;
    2.29 +import java.util.Map;
    2.30 +
    2.31 +/**
    2.32 + * Provedeme skript a do stránky vložíme jeho výstup.
    2.33 + *
    2.34 + * @author František Kučera (frantovo.cz)
    2.35 + */
    2.36 +public class Skriptování {
    2.37 +
    2.38 +	/**
    2.39 +	 * klíč = jazyk – např. bash
    2.40 +	 * hodnota = interpret – např. /bin/bash
    2.41 +	 */
    2.42 +	private static final Map<String, String> interpreti;
    2.43 +
    2.44 +	static {
    2.45 +		Map<String, String> podporovanýJazyk = new HashMap<String, String>();
    2.46 +		podporovanýJazyk.put("bash", "/bin/bash");
    2.47 +		podporovanýJazyk.put("perl", "/usr/bin/perl");
    2.48 +		podporovanýJazyk.put("php", "/usr/bin/php");
    2.49 +		podporovanýJazyk.put("python", "/usr/bin/python");
    2.50 +		interpreti = Collections.unmodifiableMap(podporovanýJazyk);
    2.51 +	}
    2.52 +
    2.53 +	/**
    2.54 +	 * TODO: podporovat i složitější scénáře (např. kompilaci),
    2.55 +	 * než jen vložení do souboru a přidání správného záhlaví.
    2.56 +	 *
    2.57 +	 * @param skript program k vykonání
    2.58 +	 * @param jazyk programovací jazyk
    2.59 +	 * @param uriStránky URI aktuálně generované stránky → proměnná prostředí
    2.60 +	 * @param nadpisStránky nadpis stránky → proměnná prostředí
    2.61 +	 * @param perexStránky perex stránky → proměnná prostředí
    2.62 +	 * @return výstup příkazu
    2.63 +	 */
    2.64 +	public static String interpretuj(String skript, String jazyk, String uriStránky, String nadpisStránky, String perexStránky) {
    2.65 +		try {
    2.66 +			System.err.println("\tInterpretuji skript v jazyce: " + jazyk);
    2.67 +			String interpret = interpreti.get(jazyk);
    2.68 +			if (interpret == null) {
    2.69 +				System.err.println("Neznámý skriptovací jazyk: " + jazyk);
    2.70 +				return null;
    2.71 +			} else {
    2.72 +				File f = File.createTempFile("xml-web-generátor-", ".skript");
    2.73 +				f.deleteOnExit();
    2.74 +
    2.75 +				PrintStream ps = new PrintStream(f);
    2.76 +				ps.print("#!");
    2.77 +				ps.println(interpret);
    2.78 +				ps.println();
    2.79 +				ps.print(skript);
    2.80 +				ps.close();
    2.81 +
    2.82 +				f.setExecutable(true);
    2.83 +
    2.84 +				String[] prostředí = new String[]{
    2.85 +					"LANG=" + System.getenv("LANG"),
    2.86 +					"USER=" + System.getenv("USER"),
    2.87 +					"XWG_STRANKA_URI=" + uriStránky,
    2.88 +					"XWG_STRANKA_SOUBOR=" + (new File(new URI(uriStránky)).getAbsolutePath()),
    2.89 +					"XWG_STRANKA_NADPIS=" + nadpisStránky,
    2.90 +					"XWG_STRANKA_PEREX=" + perexStránky
    2.91 +				};
    2.92 +
    2.93 +
    2.94 +
    2.95 +				Runtime r = Runtime.getRuntime();
    2.96 +				Process p = r.exec(new String[]{f.getAbsolutePath()}, prostředí);
    2.97 +
    2.98 +				String výsledek = načtiProud(p.getInputStream());
    2.99 +				String chyby = načtiProud(p.getErrorStream());
   2.100 +
   2.101 +				p.waitFor();
   2.102 +
   2.103 +				/**
   2.104 +				 * TODO: podporovat zvláštní návratový kód, kterým skript řekne,
   2.105 +				 * že výstupem je XML a má se vložit jako fragment do dokumentu,
   2.106 +				 * ne jako prostý text.
   2.107 +				 */
   2.108 +				if (p.exitValue() == 0) {
   2.109 +					if (chyby.length() > 0) {
   2.110 +						System.err.println("--- Cyhbový výstup skriptu -----");
   2.111 +						System.err.println(chyby);
   2.112 +						System.err.println("--------------------------------");
   2.113 +					}
   2.114 +
   2.115 +					return výsledek.trim();
   2.116 +				} else {
   2.117 +					System.err.println("--- Standardní výstup skriptu: -----");
   2.118 +					System.err.println(výsledek);
   2.119 +					System.err.println("--- Cyhbový výstup skriptu: ---------");
   2.120 +					System.err.println(chyby);
   2.121 +					System.err.println("--------------------------------------");
   2.122 +					throw new RuntimeException("Návratová hodnota: " + p.exitValue());
   2.123 +				}
   2.124 +			}
   2.125 +		} catch (Exception e) {
   2.126 +			System.err.println("Došlo k chybě při vykonávání skriptu v jazyce: " + jazyk);
   2.127 +			System.err.println("--------");
   2.128 +			System.err.println(skript);
   2.129 +			System.err.println("--------");
   2.130 +			e.printStackTrace(System.err);
   2.131 +			return null;
   2.132 +		}
   2.133 +	}
   2.134 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/šablona/makra/skriptování.xsl	Sat Jun 23 18:00:41 2012 +0200
     3.3 @@ -0,0 +1,46 @@
     3.4 +<?xml version="1.0" encoding="UTF-8"?>
     3.5 +<!--
     3.6 +XML Web generátor – program na generování webových stránek
     3.7 +Copyright © 2012 František Kučera (frantovo.cz)
     3.8 +
     3.9 +This program is free software: you can redistribute it and/or modify
    3.10 +it under the terms of the GNU General Public License as published by
    3.11 +the Free Software Foundation, either version 3 of the License, or
    3.12 +(at your option) any later version.
    3.13 +
    3.14 +This program is distributed in the hope that it will be useful,
    3.15 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.17 +GNU General Public License for more details.
    3.18 +
    3.19 +You should have received a copy of the GNU General Public License
    3.20 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
    3.21 +-->
    3.22 +<xsl:stylesheet version="2.0"
    3.23 +	xmlns="http://www.w3.org/1999/xhtml"
    3.24 +	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro"
    3.25 +	xmlns:j="java:cz.frantovo.xmlWebGenerator.makra.Skriptování"
    3.26 +	xmlns:s="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
    3.27 +	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    3.28 +	exclude-result-prefixes="m j s">
    3.29 +
    3.30 +	<!--
    3.31 +		Skriptování
    3.32 +		***********
    3.33 +		Provedeme skript zadaný v těle elementu a jeho výstup vložíme do stránky.
    3.34 +		*
    3.35 +		@jazyk programovací jazyk, např. bash, perl, php
    3.36 +		@src skript uložený v souboru místo v těle elementu
    3.37 +	-->
    3.38 +	<xsl:template match="m:skript">
    3.39 +		<!--
    3.40 +		TODO:
    3.41 +			- ošetření chyb
    3.42 +			- nastavení z web.conf (zákaz nebo ignorace skriptů)
    3.43 +			- podpora vkládání fragmentů XML, ne jen prostého textu
    3.44 +		-->
    3.45 +		<xsl:value-of select="j:interpretuj(text(), @jazyk, document-uri(/), //s:stránka/s:nadpis/text(), //s:stránka/s:perex/text())"/>
    3.46 +	</xsl:template>
    3.47 +
    3.48 +</xsl:stylesheet>
    3.49 +