summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/README38
-rw-r--r--tools/atom-limit.xsl27
-rw-r--r--tools/atom-sort.xsl29
-rw-r--r--tools/html-to-atom-dump.xsl110
-rwxr-xr-xtools/html-to-atom.sh19
-rwxr-xr-xtools/publish.sh8
-rw-r--r--tools/skeleton.xhtml46
-rw-r--r--tools/skeleton.xml15
-rwxr-xr-xtools/xml-to-html.sh12
-rw-r--r--tools/xml-to-html.xsl90
10 files changed, 394 insertions, 0 deletions
diff --git a/tools/README b/tools/README
new file mode 100644
index 0000000..c7bf4c9
--- /dev/null
+++ b/tools/README
@@ -0,0 +1,38 @@
+These are the tools I use for my personal web page authoring.
+
+The scripts can be improved to process just the modified files (and to
+be less hacky in general), the XSLTs can be made more generic, but it
+works for now, and is pretty simple.
+
+
+Editing:
+- skeleton.xml is the primary skeleton to start with, for *.xhtml
+ files in ~/homepage/src/.
+
+This stage is mostly needed to get unified styles, metadata
+properties, and other bits in case if I'll change them. The same can
+be achieved by processing (X)HTML files, but such a processing may get
+tricky, and it's also nicer to have a less verbose skeleton.
+
+Editing is done with the emacs html-mode, with
+<https://github.com/defanor/html-wysiwyg>.
+
+
+HTML:
+
+- xml-to-html.sh translates source files into actual (X)HTML in
+ ~/homepage/ by applying xml-to-html.xsl to them.
+
+
+Atom feed:
+
+- html-to-atom-dump.xsl dumps HTML files into a single atom feed.
+- atom-sort.xsl sorts those by modification date.
+- atom-limit.xsl limits them, taking the newest entries.
+- html-to-atom.sh finds source files, and pipes them through the
+ XSLTs.
+
+
+Publishing:
+
+- publish.sh runs the above two and uploads the files with rsync.
diff --git a/tools/atom-limit.xsl b/tools/atom-limit.xsl
new file mode 100644
index 0000000..2b6a285
--- /dev/null
+++ b/tools/atom-limit.xsl
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.w3.org/2005/Atom"
+ version="1.0">
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="atom:feed">
+ <feed>
+ <xsl:apply-templates select="node()[not(self::atom:entry)]" />
+ <!-- Take the top 10 entries. -->
+ <xsl:apply-templates select="atom:entry[position()&lt;10]" />
+ </feed>
+ </xsl:template>
+
+ <!-- Copy everything else -->
+ <xsl:template match="node()" priority="0">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/atom-sort.xsl b/tools/atom-sort.xsl
new file mode 100644
index 0000000..a00b599
--- /dev/null
+++ b/tools/atom-sort.xsl
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.w3.org/2005/Atom"
+ version="1.0">
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates />
+ </xsl:template>
+
+ <xsl:template match="atom:feed">
+ <feed>
+ <xsl:apply-templates select="node()[not(self::atom:entry)]" />
+ <!-- Sort by modification date, descending. -->
+ <xsl:apply-templates select="atom:entry">
+ <xsl:sort select="atom:updated" order="descending"/>
+ </xsl:apply-templates>
+ </feed>
+ </xsl:template>
+
+ <!-- Copy everything else -->
+ <xsl:template match="node()" priority="0">
+ <xsl:copy-of select="." />
+ </xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/html-to-atom-dump.xsl b/tools/html-to-atom-dump.xsl
new file mode 100644
index 0000000..fce78a2
--- /dev/null
+++ b/tools/html-to-atom-dump.xsl
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.w3.org/2005/Atom"
+ version="1.0">
+ <xsl:output method="xml" indent="yes"/>
+ <xsl:variable name="baseIRI">
+ <xsl:text>https://defanor.uberspace.net/</xsl:text>
+ </xsl:variable>
+
+ <!-- Feed -->
+ <xsl:template match="/">
+ <feed>
+ <title>defanor's notes</title>
+ <link rel="self" href="{$baseIRI}atom.xml" />
+ <link rel="alternate" href="{$baseIRI}" />
+ <id>
+ <xsl:value-of select="$baseIRI" />
+ </id>
+ <!--
+ Setting <updated> statically, since it applies to some
+ meaningful feed updates. Perhaps should be modified on
+ metadata changes.
+ -->
+ <updated>2018-04-14T10:00:00Z</updated>
+ <xsl:apply-templates select="/list/entry" />
+ </feed>
+ </xsl:template>
+
+ <!-- Turns index entries into Atom entries -->
+ <xsl:template match="entry">
+ <xsl:variable name="localPath">
+ <xsl:text>../</xsl:text>
+ <xsl:value-of select="@name" />
+ </xsl:variable>
+ <xsl:variable name="doc" select="document($localPath)" />
+ <entry>
+ <link rel="alternate" href="{$baseIRI}{@name}" />
+ <id>
+ <xsl:text>https://defanor.uberspace.net/</xsl:text>
+ <xsl:value-of select="@name" />
+ </id>
+ <!-- Setting this statically for now. -->
+ <author>
+ <name>defanor</name>
+ </author>
+ <xsl:apply-templates mode="atom-entry" select="$doc" />
+ </entry>
+ </xsl:template>
+
+ <xsl:template mode="atom-entry" match="/ | xhtml:head | xhtml:html">
+ <xsl:apply-templates mode="atom-entry" />
+ </xsl:template>
+
+ <!-- Title -->
+ <xsl:template mode="atom-entry" match="xhtml:title">
+ <title>
+ <xsl:value-of select="." />
+ </title>
+ </xsl:template>
+
+ <!-- Description/summary -->
+ <xsl:template mode="atom-entry"
+ match="xhtml:meta[@name='description' or
+ @property='dc:description schema:description']">
+ <summary>
+ <xsl:value-of select="@content" />
+ </summary>
+ </xsl:template>
+
+ <!--
+ Atom is rather strict in its date-time requriements. It's not
+ always convenient or useful to be that strict in HTML metadata,
+ so might be better to introduce some check and conversion.
+ -->
+ <!-- Publication date -->
+ <xsl:template mode="atom-entry"
+ match="xhtml:meta[@property='dc:issued schema:datePublished']">
+ <published>
+ <xsl:value-of select="@content" />
+ </published>
+ </xsl:template>
+
+ <!-- Modification date -->
+ <xsl:template mode="atom-entry"
+ match="xhtml:meta[@property='dc:modified schema:dateModified']">
+ <updated>
+ <xsl:value-of select="@content" />
+ </updated>
+ </xsl:template>
+
+ <!-- Body/content -->
+ <xsl:template mode="atom-entry" match="xhtml:body">
+ <content type="xhtml">
+ <!--
+ "the content of atom:content MUST be a single XHTML div
+ element"
+ -->
+ <xhtml:div>
+ <xsl:copy-of select="*" />
+ </xhtml:div>
+ </content>
+ </xsl:template>
+
+ <!-- Skip everything else -->
+ <xsl:template mode="atom-entry" match="node()" priority="0" />
+
+</xsl:stylesheet>
diff --git a/tools/html-to-atom.sh b/tools/html-to-atom.sh
new file mode 100755
index 0000000..aa665b0
--- /dev/null
+++ b/tools/html-to-atom.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Composes an atom feed out of XHTML files.
+
+BASEDIR=~/homepage
+TOOLS="${BASEDIR}/tools"
+SOURCES="${BASEDIR}/src"
+ATOM="${BASEDIR}/atom.xml"
+
+(echo '<?xml version="1.0" encoding="UTF-8"?>' &&
+ echo '<list>' &&
+ find "${BASEDIR}" -name '*.xhtml' |
+ grep -Ev "^(${TOOLS}|${SOURCES}).*" |
+ sed -e "sS^${BASEDIR}\(.*\)S<entry name=\"\\1\" />S" &&
+ echo '</list>') |
+ xsltproc "${TOOLS}/html-to-atom-dump.xsl" - |
+ xsltproc "${TOOLS}/atom-sort.xsl" - |
+ xsltproc "${TOOLS}/atom-limit.xsl" - |
+ xmllint --format --nsclean - > "${ATOM}"
diff --git a/tools/publish.sh b/tools/publish.sh
new file mode 100755
index 0000000..5a6cbea
--- /dev/null
+++ b/tools/publish.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+TOOLS=~/homepage/tools
+
+${TOOLS}/xml-to-html.sh
+${TOOLS}/html-to-atom.sh
+rsync --exclude '.*' --exclude '*.org' --exclude 'src/' --exclude 'tools/' \
+ -avz . uberspace.net:homepage/web/
diff --git a/tools/skeleton.xhtml b/tools/skeleton.xhtml
new file mode 100644
index 0000000..3e157b7
--- /dev/null
+++ b/tools/skeleton.xhtml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
+ prefix="dc: http://purl.org/dc/terms/
+ rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
+ schema: http://schema.org/
+ foaf: http://xmlns.com/foaf/0.1/
+ dbr: http://dbpedia.org/resource/
+ home: https://defanor.uberspace.net/"
+ typeof="dc:Text schema:Article foaf:Document">
+ <head>
+ <title property="dc:title schema:name foaf:name">FILL ME</title>
+ <meta name="robots" content="noarchive" />
+ <meta name="description"
+ property="dc:description schema:description"
+ content="FILL ME" />
+ <meta name="keywords"
+ property="schema:keywords"
+ content="FILL ME" />
+ <meta property="dc:created schema:dateCreated"
+ datatype="schema:Date"
+ content="FILL ME" />
+ <meta property="dc:issued schema:datePublished"
+ datatype="schema:Date"
+ content="FILL ME" />
+ <meta property="dc:modified schema:dateModified"
+ datatype="schema:Date"
+ content="FILL ME" />
+ <link property="dc:subject schema:about foaf:primaryTopic"
+ href="FILL ME" />
+ <link property="dc:creator schema:creator foaf:maker"
+ href="../foaf.rdf#me" />
+ <link property="dc:isPartOf schema:isPartOf"
+ href="https://defanor.uberspace.net/" />
+ <link rel="stylesheet" title="Dark, blueish"
+ href="../xhtml-rdfa-dark.css" />
+ <link rel="alternate stylesheet" title="No colourisation"
+ href="../xhtml-rdfa.css" />
+ <link rel="alternate stylesheet" title="Light, beige"
+ href="../xhtml-rdfa-light.css" />
+ </head>
+
+ <body>
+ FILL ME
+ </body>
+</html>
diff --git a/tools/skeleton.xml b/tools/skeleton.xml
new file mode 100644
index 0000000..a65f179
--- /dev/null
+++ b/tools/skeleton.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document>
+ <meta title=""
+ description=""
+ keywords=""
+ created=""
+ published=""
+ modified=""
+ primaryTopic="">
+ <topic iri="" />
+ </meta>
+ <body xmlns="http://www.w3.org/1999/xhtml">
+
+ </body>
+</document>
diff --git a/tools/xml-to-html.sh b/tools/xml-to-html.sh
new file mode 100755
index 0000000..c05d749
--- /dev/null
+++ b/tools/xml-to-html.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Translates simplified documents from src/
+
+BASEDIR=~/homepage
+TOOLS="${BASEDIR}/tools"
+SOURCES="${BASEDIR}/src"
+
+find "${SOURCES}" -name '*.xhtml' |
+ sed -e "sS^${SOURCES}SS" |
+ xargs -Ifile xsltproc -o "${BASEDIR}/file" \
+ "${TOOLS}/xml-to-html.xsl" "${SOURCES}file"
diff --git a/tools/xml-to-html.xsl b/tools/xml-to-html.xsl
new file mode 100644
index 0000000..1b1358d
--- /dev/null
+++ b/tools/xml-to-html.xsl
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.w3.org/1999/xhtml"
+ version="1.0">
+ <xsl:output method="xml" indent="yes"/>
+
+ <xsl:template match="/">
+ <xsl:apply-templates select="document" />
+ </xsl:template>
+
+ <xsl:template match="document">
+ <xsl:text disable-output-escaping='yes'>
+ &lt;!DOCTYPE html&gt;
+ </xsl:text>
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
+ prefix="dc: http://purl.org/dc/terms/
+ rdfs: http://www.w3.org/1999/02/22-rdf-syntax-ns#
+ schema: http://schema.org/
+ foaf: http://xmlns.com/foaf/0.1/
+ dbr: http://dbpedia.org/resource/
+ home: https://defanor.uberspace.net/"
+ typeof="dc:Text schema:Article foaf:Document">
+ <head>
+ <xsl:apply-templates select="meta" />
+ </head>
+ <xsl:copy-of select="xhtml:body" />
+ </html>
+ </xsl:template>
+
+ <!-- Metadata -->
+ <xsl:template match="meta">
+ <!-- Only title is required -->
+ <title property="dc:title schema:name foaf:name">
+ <xsl:value-of select="@title" />
+ </title>
+ <xsl:if test="@description">
+ <meta name="description"
+ property="dc:description schema:description"
+ content="{@description}" />
+ </xsl:if>
+ <xsl:if test="@keywords">
+ <meta name="keywords"
+ property="schema:keywords"
+ content="{@keywords}" />
+ </xsl:if>
+ <xsl:if test="@created">
+ <meta property="dc:created schema:dateCreated"
+ datatype="schema:Date"
+ content="{@created}" />
+ </xsl:if>
+ <xsl:if test="@published">
+ <meta property="dc:issued schema:datePublished"
+ datatype="schema:Date"
+ content="{@published}" />
+ </xsl:if>
+ <xsl:if test="@modified">
+ <meta property="dc:modified schema:dateModified"
+ datatype="schema:Date"
+ content="{@modified}" />
+ </xsl:if>
+ <xsl:if test="@primaryTopic">
+ <link property="dc:subject schema:about foaf:primaryTopic"
+ href="{@primaryTopic}" />
+ </xsl:if>
+
+ <xsl:apply-templates select="topic" />
+
+ <!-- The rest is fixed metadata -->
+ <link property="dc:creator schema:creator foaf:maker"
+ href="/foaf.rdf#me" />
+ <link property="dc:isPartOf schema:isPartOf"
+ href="https://defanor.uberspace.net/" />
+ <link rel="stylesheet" title="Dark, blueish"
+ href="/xhtml-rdfa-dark.css" />
+ <link rel="alternate stylesheet" title="No colourisation"
+ href="/xhtml-rdfa.css" />
+ <link rel="alternate stylesheet" title="Light, beige"
+ href="/xhtml-rdfa-light.css" />
+ <meta name="robots" content="noarchive" />
+ </xsl:template>
+
+ <!-- Additional topics -->
+ <xsl:template match="topic">
+ <link property="dc:subject schema:about foaf:topic"
+ href="{@iri}" />
+ </xsl:template>
+
+</xsl:stylesheet>