三自排版运动(四):XSLT与嵌入视频

缘起

之前提到了,我在简书主要以Markdown格式上传,但还有五篇「不得不」使用富文本编辑器的文章,因为其中包括了「视频」。

所以,先睁眼看世界,看看境外赛博朋克英特纳雄耐尔主义者当中的Markdown用户是怎样对待这个问题的。

众所周知,Markdown有很多变种和扩展,其中追加了「流程图」「甘特图」等适合码农的功能的那种,称为「markdown-it」,也就是GitHub上面使用的那种。于是,GitHub用户开了一个项目,唤作「markdown-it-video」,进一步扩展。

当然这需要服务器端支持,但是可以先观察其语法,在本地通过XML/XSLT模拟嘛。由于各个视频网站的架构不同格式不同,当然引用视频的方式也不同。目前「markdown-it-video」支持五个站点,语法则是统一的。

@[youtube](dQw4w9WgXcQ)
@[vimeo](19706846)
@[vine](etVpwB7uHlw)
@[prezi](1kkxdtlp4241)
@[osf](kuvg9)

也就是说,提供的信息只有「站点」和「视频标识」,插件在内部根据「站点」不同生成不同的针对性的代码也就是「链接」的形式。其它站点当然就不管了。

那么,不仅我中华兲朝上国自有国情在此,就是在其它二百多个联合国成员注册的视频站点,都有自己的「特色」,不可能面面俱到。

于是,本篇的目标已经限定了,最低纲领是把迄今为止码字中用到的外部视频链接进行处理,最高纲领是挑几个不同的视频站点进行针对性处理,技术上能实现就结束。

工欲善其事必先利其器

虽然说过了,运行环境只需要「浏览器」,但是编写XSLT并进行调试的过程,若是单纯凭借「文本编辑器」就有些费劲了,浏览器提供的错误信息并不足够充沛。

对于XML应用来说,「可视化集成开发环境」也有,虽然工作效率较高,但通常成本也很高。这里就列举两个曾经用过但被贫穷限制了购买力而不是想象力的我喜忧掺半感慨万分的软件(套装)。

一个是「Oxygen Xml Editor」,已经覆盖了常见的XML应用范围。

还有一个是豪华版旗舰套装「Altova MissionKit」,其中一个产品「XmlSpy」就大致对应了各种「Xml Editor」,而其它产品各有高附加值。

顺便请忠君爱国童年才俊们注意,这个「Altova」与美帝灯塔国没关系,是总部设在维也纳的德意志民族神圣罗马帝国企业,在线商店里面除了北美地区之外的定价单位都是欧元。

正所谓「临川羡鱼不如退而结网」者也,对于眼下面对的需求,还得通过「三自」方式搞定。在已经有了「VS Code」等免费且功能足够的文本编辑器的情况下,可以利用之前提到过的第三方软件,通常是开源至少免费的。

于是,按照W3C以及与其关系密切的机构和个人的推荐,搜到了「Saxon」,提供了C/C++/PhpJava™.NetJavaScript™环境,其中「Home Edition」是开源的,下载链接在SourceForge上。

对于Windows用户来说,建议下载.Net版,因为安装包已经包括了命令行工具,直接用就可以,不需要自己编译或依赖JRE。而JavaScript™版也可以顺便下来用于在线处理。

Apache也有相应的开源成果「Xalan」,不过同样需要自行编译或者以「java -jar」方式启动。这点「麻烦」对于码农来说这不算啥,但对于我如今这种极力避免编程的状态,并不是在项目中使用「库」而是执行「转换」操作,还得单独下载Java™,何必呢。

最低纲领

不废话,先把五篇文章内所有用过的视频罗列成XML格式:

«testVideo.xml»

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="./testVideo.xsl"?>
<stuff title="视频测试" caption="以下是迄今为止「不得不」使用「富文本编辑器」上传的视频内容">
    <page heading="《范版西幻设定集》注释〔廿六〕" link="https://www.zybuluo.com/fanhan/note/1171657">
        <video artist="国王合唱团" title="解构约翰" site="youku" vid="XNjQ3OTU0NDQ=">改编自『巴赫』《D小调托卡塔与赋格》(编号BWV565)</video>
        <video artist="巴赫" title="D小调托卡塔与赋格(BWV565)" site="youku" vid="XNjQxNTM5Njg=">管风琴原版,键盘操作可视化</video>
        <video artist="Ю́рий Па́влович Казако́в" title="D小调托卡塔与赋格(BWV565)" site="youku" vid="XMzA2OTY4NDg0">巴扬改编版</video>
        <video artist="Edson Lopes" title="D小调托卡塔与赋格(BWV565)" site="youku" vid="XMTg5NzQ4NjYwNA==">古典吉他改编版</video>
        <video artist="Robert Tiso" title="D小调托卡塔与赋格(BWV565)" site="youku" vid="XMTcwODc3NTg4">玻璃杯版</video>
        <video artist="Naudo" title="Take Me Home, Country Roads" site="youku" vid="XMjU0MzcxNDg=">美国乡村音乐,John Denver原唱</video>
        <video artist="И́горь Витáльевич Преснякóв" title="帕赫贝尔卡农" site="youku" vid="XMjUyODQ2MTEy">古典吉他改编版</video>
        <video artist="Los Angeles Guitar Quartet" title="帕赫贝尔卡农" site="youku" vid="XMjQzOTU0MzM2">洛杉矶吉它四人帮合奏改编版</video>
        <video artist="帕赫贝尔" title="D大调卡农与吉格" site="youku" vid="XMTk0MTY5MDgw">弦乐四重奏原版,键盘操作可视化对照同步乐谱</video>
        <video artist="Steve Kaufman" title="Black Mountain Rag" site="youku" vid="XNjA1NDY3MTU2">吉它拨片名曲</video>
        <video artist="MC Micker &amp; DJ Sven" title="Holiday Rap" site="youku" vid="XNDY0Mzc5MDIw">俩荷兰歌手的英语饶舌</video>
        <video artist="2PAC" title="Life Goes On" site="youku" vid="XMzM0NjEzNTYw">「非洲裔美国人」(African American或American African,我也不知道当前英语工作者讨论的结果是什么)的日常之真实写照</video>
        <video artist="2PAC" title="Hit'em Up" site="youku" vid="XMzg5ODY3MTg4">代表西部挑衅东部,可参考NBA总决赛冠军归属一起理解</video>
        <video artist="Eminem" title="I'll Hit'em Up" site="youku" vid="XNjk5MTA4OTY=">翻唱,以东部身份回击,可参考NBA总决赛冠军归属一起理解</video>
        <video artist="Michael Bolton" title="Lean On Me" site="youku" vid="XMjgyNzExMDQ0">于1993年初美帝灯塔国应景冻蒜大统领克林顿登基典礼上演唱</video>
    </page>
    <page heading="《范版西幻设定集》注释〔三十〕" link="https://www.zybuluo.com/fanhan/note/1171662">
        <video artist="Michael Bolton" title="Go the Distance" site="youku" vid="XMzg2MDI5OTY=">动画片《赫拉克勒斯》主题曲(英语版)</video>
        <video artist="Ricky Martin" title="No Importa La Distancia" site="youku" vid="XMTY0OTU1Njg=">动画片《赫拉克勒斯》主题曲(西班牙语版)</video>
        <video artist="郭兰英" title="我的祖国" site="youku" vid="XMjg5ODU4MDc2OA==">电影《上甘岭》主题曲</video>
        <video artist="张映哲" title="英雄赞歌" site="youku" vid="XMjcxMzUzNjA2OA==">电影《英雄儿女》插曲</video>
        <video artist="Lorenzo Jovanotti" title="Serenata Rap" site="youku" vid="XMTMzNzc2MTg1Ng==">意大利语饶舌</video>
    </page>
    <page heading="《范版西幻设定集》注释〔卅六〕" link="https://www.zybuluo.com/fanhan/note/1171667">
        <video artist="James P. Carrell" title="Amazing Grace" site="youku" vid="XMjUzNjI2MTcwOA==">某同名基督教赞美诗配乐</video>
        <video artist="凯尔特人" title="Highland Cathedral" site="youku" vid="XMjA1NjI2MzY0">苏格兰民乐</video>
        <video artist="凯尔特人" title="Cock O' the North" site="youku" vid="XNzU2NzY0NDcy">苏格兰民乐</video>
        <video artist="凯尔特人" title="Auld Lang Syne" site="youku" vid="XMzg1NTE2NDM2">苏格兰民歌</video>
        <video artist="James Horner" title="My Heart Will Go On" site="youku" vid="XMTU1NDI0ODU4OA==">电影《泰坦尼克》配乐</video>
        <video artist="James Horner" title="A Gift Of A Thistle" site="youku" vid="XNjgyOTg5OTMy">电影《勇敢的心》配乐</video>
        <video artist="Luca Stricagnoli" title="A Gift Of A Thistle" site="youku" vid="XNzIzMzAxMTc2">吉它指弹改编版</video>
    </page>
    <page heading="《范版西幻设定集》注释〔卅七〕" link="https://www.zybuluo.com/fanhan/note/1171669">
        <video artist="Johnny" title="罪恶装备:启示者" site="youku" vid="XMTU3OTQzMDA5Mg==">《罪恶装备:启示者》街机通关视频Johnny篇(日文字幕)</video>
    </page>
    <page heading="《范版西幻设定集》注释〔卌九〕" link="https://www.zybuluo.com/fanhan/note/1171682">
        <video artist="喜納昌吉" title="花" site="youku" vid="XMTIwNTI2OTI4">曾被台湾音乐界翻唱,从一首「反战歌曲」改编成了「情歌」。</video>
    </page>
</stuff>

然后针对这个格式,写出XSLT操作:

«testVideo.xsl»

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="5.0" encoding="utf-8" indent="yes" />
<xsl:template match="stuff">
    <html>
    <head>
    <title><xsl:value-of select="@title" /></title>
    <style>
        abbr{font-size:1.2rem;}
        abbr::before{color:red;content:"{©";padding-right:0.5rem;}
        abbr::after{color:red;content:"™®}";padding-left:0.5rem;}
        cite{font-style:normal;font-size:1.2rem;}
        cite::before{color:blue;content:"《";font-weight:bold;padding-right:0.5rem;}
        cite::after{color:blue;content:"》";font-weight:bold;padding-left:0.5rem;}
        div.video{border:none;}
        div.remark{margin-right:1rem;padding:0 1rem;float:left;width:320px;height:480px;}
        iframe{border:none;width:640px;height:480px;}
    </style>
    </head>
    <body>
    <h1><xsl:value-of select="@caption" /></h1>
    <xsl:apply-templates />
    </body>
    </html>
</xsl:template>
<xsl:template match="video">
    <h2><a href="{@link}"><xsl:value-of select="@heading" /></a></h2>
    <xsl:apply-templates />
</xsl:template>
<xsl:template match="video">
    <div class="video">
        <div class="remark">
            <p><abbr><xsl:value-of select="@artist" /></abbr></p>
            <p><cite><xsl:value-of select="@title" /></cite></p>
            <p class="comment"><xsl:value-of select="." /></p>
        </div>
        <iframe src="http://player.youku.com/embed/{@vid}"></iframe>
    </div><br />
</xsl:template>
</xsl:transform>

执行转换操作很简单,装上「Saxon」之后使用命令行就行:

Transform.exe -t -s:testVideo.xml -xsl:testVideo.xsl -o:temp.html

如果出错,命令窗口里面会有错误信息显示,精确到哪行哪列,照着改就是了。这就比每次启动浏览器看其中含糊的提示要方便,在「开发」阶段应该如此。

转换成功之后,打开temp.html文件在浏览器内观察到结果显示正常。双击testVideo.xml文件,启动IE会自动转换,显示正常,但是由于视频太多「显示驱动程序崩溃并自动恢复」了。于是拖进FireFox里面,效果如下:

转换结果页面
转换结果页面

使用的CSS很简单,都是前几篇提到过的。而本篇的重点XSLT,是使用了递归下降的模板(xsl-template),对每个节点的处理都是「陈力就列不能者止」。对数据的处理也只有「xsl:value-of」这最简单最基本的「拿来主义」。

这里要特意提醒一点,FireFox不支持xsl:text」的「disable-output-escaping」设置,输出字面常量就是会转义,页面上会把「<>"'&」这些原原本本显示出来,解决方案就是上面代码所体现的,直接写html并在其中引用字面变量「{@title}」「{@vid}」什么的。

最高纲领

因为码字的时候这些视频素材都是在同一个站点「优酷」找到的,所以上面的处理当中没有考虑到「具体情况具体分析」「我大某站自有站情在此」相关事宜,因此那个「site」属性值并没有被用到。

所以,顺便多找了个几个视频站点,从活跃色目帐号经常主动推送到我眼皮底下于是知名度比较高的那些开始,选择不代表本人的任何倾向,不需要做任何解释。

而素材也不找「政治敏感」容易被「亦当删去」的那些,搜索使用关键字「BWV565」,也就是各种风格改编版《巴赫D小调托卡塔与赋格》,还是之前没用过的。

存储数据的XML文件如下:

«videoTest.xml»

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="./videoTest.xsl"?>
<document>
    <stuff title="测试视频" capition="对不同站点的链接分别处理">
        <video title="费卢西奥・布索尼改编单钢琴版《巴赫D小调托卡塔与赋格》(BWV565)" site="tudou" vid="XMjIyMDUyNDQ4NA==" />
        <video title="长笛独奏《巴赫D小调托卡塔与赋格》(BWV565)" site="bilibili" vid="9737969" />
        <video title="Luc Beauséjour 脚键盘羽管键琴pedal harpsichord 演奏 BWV565" site="iqiyi" vid="43b09fdeb34aaa31b960066795c34e15" />
        <video title="(铜管五重奏)巴赫《D小调托卡塔与赋格》BWV565" site="iqiyi" vid="a785806017761ac9f128023d64b66690" />
    </stuff>
</document>

格式更简单,就是罗列三个站点的四个视频,只有属性值没有节点值,就当数据库快照那么理解好了。

针对性转换的XSL如下:

«videoTest.xsl»

<?xml version="1.0" encoding="utf-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" version="5.0" encoding="utf-8" indent="yes" />
<xsl:template match="stuff">
    <html>
    <head>
    <title><xsl:value-of select="@title" /></title>
    <style>
        div.video{width:640px;height:480px;border:1px solid black;}
        iframe{width:100%;height:100%;border:none;}
    </style>
    </head>
    <body>
    <h1><xsl:value-of select="@caption" /></h1>
    <xsl:apply-templates />
    </body>
    </html>
</xsl:template>
<xsl:template match="video">
    <xsl:variable name="title" select="@title" />
    <xsl:variable name="site" select="@site" />
    <xsl:variable name="vid" select="@vid" />
    <div>
        <h2><xsl:value-of select="@title" /></h2>
        <div class="video">
        <xsl:if test="$site='tudou'">
            <p>该站不支持外链,请点击下述链接观看:</p><br />
            <p><a href="http://new-play.tudou.com/v/{$vid}.html" target="_Blank"><xsl:value-of select="$title" /></a></p>
        </xsl:if>
        <xsl:if test="$site=iqiyi">
            <iframe src="http://open.iqiyi.com/developer/player_js/coopPlayerIndex.html?vid={$vid}&amp;tvId=4950238209&amp;accessToken=2.f22860a2479ad60d8da7697274de9346&amp;appKey=3955c3425820435e86d0f4cdfe56f5e7&amp;appId=1368"></iframe>
        </xsl:if>
        <xsl:if test="$site='bilibili'">
            <iframe src="http://player.bilibili.com/player.html?aid={$vid}&amp;cid=16094944&amp;page=1"></iframe>
        </xsl:if>
        </div>
    </div>
</xsl:template>
</xsl:transform>

转换方式同上,在FireFox当中显示效果如下:

转换结果页面
转换结果页面

其中用到了「局部变量」,还使用「xsl-if」进行判断。其中「土豆」不提供「分享」外链,目前在线使用html5格式视频,所以直接给链接。其实对于多个站点还可以用「xsl-choose」「xsl-when」「xsl-otherwise」操作,就像各种真の编程语言当中「if-elseif-else」「switch-case」块那样。

后记

本篇「字」数不多,但是其中尽可能简短的「代码」也是我亲手运用十个手指头辛辛苦苦敲出来(并亲自将八阿哥斩尽杀绝)的吖,算广义「码字」吧。

到现在为止,已经上传的文章当中与Markdown格式相关的遗留问题都已经解决,至少是有了解决方案在本地可以实现的那种。

刚发现还没扯到政治和意识形态之上,浑身不舒服,于是最后先挑个头吧,将来单独「惹是生非」展开了说。

先参考经济学上的「恩格尔系数」,说食物支出占收入比例越大就越贫穷,考虑「温饱」问题只管饱不管温,那是由于部分少数民族还有裹块兽皮围个草裙的传统风俗习惯,不需要纺织业产能。那么,套用到赛博朋克虚拟经济之上,作为生产工具的「软硬件采购支出」在总成本当中所占比例越高,相应生产者就越「低端」,这个概念各位业内有意见么?

哪怕从个人角度出发,从零开始配置工作环境的一次性支出预算想必不少,这成本要摊平到整个寿命周期当中。并且,各种专业软件经常时常需要升级,还有一些许可是定时「租借」的,这些都属于维护成本。也就是说,「软硬件采购支出」对于工作品质的影响,好比食物对于生活品质的影响一样,占比越大,体现出品质越「低劣」。

因此,由于核心技术把持在以美帝灯塔国为首的发达国家之中,硬件成本减不掉,为了降低成本扩大利润,赛博朋克企业纷纷不约而同采取了压缩软件采购预算的手段。其中有合法的,就是用开源和免费软件替代品;当然也有不合法的,那就是盗版。选择前者对使用者素质要求较高,后者则对其脸皮要求较高。

2018-06-22