网络写作的开放式翻译

2020-09-08 13:13:01

如果你关注这个博客,你会看到我尝试过基于iframe的引用;这篇文章是关于开源工具的。跳至演示、实施教程和GitHub链接。

知识工具再次愉快地成为热门话题。随着这一趋势的到来,人们对世外桃源、双向超链接、知识数据库、可视化知识图等重新产生了兴趣。此时此刻,我看到大部分的重点都放在了研究方面的工具上,概念、工作流和新的、被炒作的漫游研究引领着这条道路。

我认为较少关注的是知识生产过程中的写作部分,在这一部分,像Scrivener这样的旧应用程序仍然是值得击败的。而且几乎没有人在研究读者的体验。作为一个在很大程度上迎合广大受众的博客作者,我对这些领域特别感兴趣。

书面信息在很大程度上仍然是以单个文档的形式呈现的,而书写工具是专为制作长页而设计的。但在我说这有什么问题之前,让我先对文档赞不绝口。

当人们发现超文本的最初愿景时,他们往往会忘乎所以,因为超文本涉及到一个文档网络,其中一部分被“转换”(通过超文本包括)到另一个文档中。言下之意是,读者可以遵循任何参考资料,查看原始材料-当然,这将是变革性的。然而,知识网络作为一种阅读体验的有效性是有限的。“超文本图书”是由大量相互链接的HTML页面组成的在线图书,大多不受欢迎。在我看来,这个实验的失败是非常有启发性的。

知识不是事实的积累,更不是事实及其关系的集合。事实只有在叙述中才有意义,而单页文件是一种非常有利于叙事结构的格式。广受欢迎的超文本图书(我在这里指的是Meaningness.com)在两个方面很大程度上符合这一点:1)有一个预定的阅读顺序,2)项目中较长的论文在向读者传达作者观点方面承担了大部分重任。

另一方面,今天网络发展固有的“文档”概念被印刷媒体的传统过度确定了。Web文档是静态的、已完成的工件,不会引入动态数据。这很奇怪,因为它生活在一种活的、网络的和动态的媒介上,这种媒介越来越多地被我们理解为一个空间,而不是一个东西。

例如,当我们在Web上拥有链接文档的巨大能力时,想想在文本的底部包含MLA风格的引用是多么愚蠢。为什么读者必须阅读每一条引文,或者相信作者没有断章取义,因为有超链接可用?

这一切都表明,必须在文本的连贯性和媒体的基本能力(互联网的连通性,屏幕的帧率)提供的知识工作的新机会之间达成妥协。

我自己的博客是我看到这种紧张的一个背景,我一直在努力探索让我的文本更丰富的方法。我在不同的文章中谈到的很多想法都是相互联系的。当我发表一篇文章时,我还没有看完。这些想法永存,并在后来的作品中得到更新、重用和循环。有些句子包含了我心智模型的核心定义,还有一些完整的段落可能会在断章取义的情况下有用。我正在思维地图和各种SaaSAPI背后建立我的知识网络,但我如何公开展示我的想法,使其成为凝聚力世界观的一部分?

通常情况下,人们通过简单地阻止引用自己的话来解决这个问题,但这是浪费机会。缩进块引号是一种印刷媒介发明,几乎和排字一样古老。块引用是纯文本,它实际上没有链接到原始文本或其上下文。

我一直在试验一个解决方案的想法,如果你读过最近几篇博客文章,你就会在那里看到它。我想要回答的是一个IFRAME,它显示了原始上下文中的引用,并给出了它周围的提示。实际上,这是我自己博客中的一种转换。我目前对自己的v1版本很满意,也很想看看其他人是否觉得它有用,所以我在这里把它开源,并附带了一个教程。

Open Transclude是一种UX模式,是在您自己的博客中进行网络写作的规范。下面是它的外观:

你看到的是一个卷轴锁定的IFRAME,它链接到我从博客文章“比较心理学笔记”中挑选出的一句名言。您可以使用Open Transclude,您可以将<;a>;标签放在您自己的站点上的任何位置。

12行HTML、80行SCSS、22行JS(总计4.5kb)。

Open Transclude非常简单,代码中最繁重的部分是CSS,您可以随意简化它。这就是我将其称为UX模式的原因。这不是协议。代码真的是一种商品。有趣的是它的想法和设计,而这只是一个可行的实现!您可以随心所欲地修改它。

在GitHub上,您可以找到Jekyll的参考实现。下面是您自己实现它的教程,还解释了一些技术设计决策。

以下是启动和运行Open Transclude所需的操作。

要引用您自己的信息,您需要在标记文件中为您要引用的帖子创建一个<;a>;锚点标记。如果要突出显示特定文本,请在要引用的部分周围创建<;span&>;/span&>;。请注意,这只能在您自己的网站上进行-它不能跨域工作。

首先,它会变得对自己有新的认识,而且到了现在的程度,**它会倾向于破坏它自己的经验完整性**";(强调我的)。具有讽刺意味的是,心理学仍然是我们今天拥有的最接近主流魔术或神秘艺术的东西之一。这不仅仅是因为它显然是中世纪魔法的直系后裔,正如我在今年早些时候阅读Ioan Coulianou的“文艺复兴时期的性爱与魔法”时了解到的那样。**这是一种关于自我的理论,它在现象上是准确的,客观上是错误的,而且是基于神奇的思维,即使它解构了自己**。<;/span>;心理治疗中发生的一些神奇的思维过程,如[向心理学家的移情](https://en.wikipedia.org/wiki/Transference#Transference_and_countertransference_during_psychotherapy),甚至打算对患者保持沉默,以便治疗师最有效地利用!

这是最有用的标准化组件,可以跨站点使用,因此我们将利用Jekyll的模板功能。Jekyll和其他静态站点生成器(如Kirby和Zola)支持HTML“部分”或“包含”,这样您就可以创建可重用的组件。

在/_scss或/_sass文件夹中创建一个新文件portal.scss。我称它为“门户”,因为它比“转译”短,也不容易出现拼写错误。

<;div class=";>;<;div class=";portal-head";>;<;div class=";portal-backlink";>;<;div class=";portal-title";>;来自<;span class=";portal-text-title&34;>;{{。<;a href=";{{include de.link}}";class=";门户箭头&34;>;转到文本<;span class=#34;右箭头&34;>;→<;/a&>;/div&>;/div<;/div<;div<;div ID=&#。Portal-Parent&34;>;div class=";Portal-Parent-fader-top&34;>;<;/div>;<;div class=";Portal-Parent-fader-Bottom&34;<;/div&>;<;!--我们将在此处使用Javascript填充iFrame-->。

您会立即注意到IFRAME还没有出现。就像我在上面提到的,我们将用Javascript填充它。

您还会看到我们在各个地方使用{{include._}}。Jekyll的一件很酷的事情包括它可以定义变量并将它们传递给我们的Include,这样我们就可以在我们的站点上创建可重用的组件。Dave Rupert有一篇很好的博客文章,名为“如果你想看更高级的例子!

每当您想要将此组件放入博客帖子中时,您所要做的就是将其包含在另一篇博客帖子的标记中,如下所示:

当您包含它时,您需要传入这三个变量-标题、链接和锚,这三个变量填充上面的包含项。如果您现在正在使用Jekyll进行构建,您将看到一个带有链接的空的、未设置样式的组件。到目前为止一切都很好!

这是解决我们为什么需要Javascript的好时机。读到本文的Web开发人员可能会问,为什么我们不简单地将完整的/link#with-锚放到iframe src中并完成它。不幸的是,几个浏览器上都有一个错误,当页面加载时,父文档会跳转到IFRAME。因此,我们需要在之后将iFrame加载到我们的组件中。

在portal.html中创建一个新的<;script>;标记,并将以下内容放入其中。因为它在我们的门户组件中,所以我们实际上可以将包含变量直接传递到Javascript中!只要确保他们周围有引号就行了。

<;script>;function linkFunction(Link){//将我们传入的链接拆分为基本URL和锚标记var baseSlug=link。Split(';#';)[0];var ATAG=link。Split(';#';)[1];//我们需要知道父元素,这样才能追加const parent=document。GetElementById(';ITXT-Body-{{include de.ang}}';);//现在让&/现在创建IFRAME,设置其属性,并将其附加到父元素const frame=document。CreateElement(#39;iframe;);父级。AppendChild(Frame);Frame。SetAttribute(";id";,ATAG);Frame。SetAttribute(";class";,";portal-iframe";);框架。SetAttribute(";src&34;,baseSlug);帧。SetAttribute(";scroll";,";no";);//最后,我们将创建IFRAME setTimeout(function(){const innerDoc=frame。ContentDocument||Frame。ContentWindow。Document;=innerDoc。GetElementsByName(ATAG)[0];//找到对应的span或锚标签//在引用的元素锚上设置文本修饰。SetAttribute(';class';,';PORTAL-QUOTE-TEXT';);//获取锚点相对于起始滚动位置var Offset=锚点的位置。GetBorbingClientRect()。Top;//注意:将此替换为您的主题的默认间距单位var Spacing=25//检查是否要覆盖间距//如果突出显示文本,请将其居中(锚定。InnerHTML&;&;锚。InnerHTML!==";";){Offset=偏移量-(间距*4);};//将iFrame内容跳转到锚框。ContentWindow。ScllBy(0,Offset);},1000);};linkFunction(";{{include de.link}}";);function linkFunction(Link){var baseSlug=link。Split(';#';)[0];//获取基本slug var ATAG=link。Split(';#';)[1];//获取散列变量parent=document。GetElementById(';ITXT-Body-{{include de.ang}}';);const frame=document。CreateElement(#39;iframe;);父级。AppendChild(Frame);Frame。SetAttribute(";id";,ATAG);Frame。SetAttribute(";class";,";portal-iframe";);框架。SetAttribute(";src&34;,baseSlug);帧。SetAttribute(";滚动";,";否";);setTimeout(function(){const innerDoc=frame。ContentDocument||Frame。ContentWindow。文档;锚=innerDoc。GetElementsByName(ATAG)[0];//找到对应的锚标签//在锚上设置文本修饰。SetAttribute(';class';,';PORTAL-QUOTE-TEXT';);//获取锚点相对于起始滚动位置var Offset=锚点的位置。GetBorbingClientRect()。Top;//注意:将此替换为您的主题的默认间距单位var Spacing=25//检查是否要覆盖间距//如果突出显示文本,请将其居中(锚定。InnerHTML&;&;锚。InnerHTML!==";";){Offset=偏移量-(间距*4);};//将iFrame内容跳转到锚框。ContentWindow。Scroll By(0,Offset);},1000);};<;/script>;

注意:为了使用浏览器的调试工具更轻松地进行调试,您可能还希望拥有一个portal.js文件,并使用<;script src=";/portal.js";>;<;/script>;链接到它。如果这样做,您将无法在JS中使用Include-您将需要准确地指定链接。

调用函数“linkFunction

计算IFRAME内文档顶部与其内锚定或跨距标签之间的距离,然后滚动该距离。(请记住,我们必须这样做,因为如果我们直接加载链接,它将滚动整个父文档。)。

您可能会感到疑惑:为什么我们还要将一个变量传递给iframe的父元素的类呢?ITXT-身体-看起来有点时髦。

这样做的原因是为了支持每个帖子的多个Transclusion。每次包含这段HTML时,都会调用此函数,因此我们需要确保它指定了正确的父级。如果您不在这里指定它,Javascript将只找到POST中的第一个ITXT-Body,并用您试图加载的每个IFRAME填充它。如果向后滚动,您将看到它与portal.html完全匹配。

该函数将一个新的iframe附加到门户父div,将滚动设置为no,并给它一个类,这样我们就可以设置样式了。

此时,您只需转到GitHub,获取包含的portal.scss文件,并按您所需设置样式即可。我只想在这里留下一些建议。

这里最有趣的设计元素是在IFRAME的顶部和底部使其看起来像是文本逐渐淡出的衬布。这实际上是通过两个绝对定位的渐变来实现的:

.portal-父{overflow:隐藏;位置:相对;宽度:100%;框大小:边框;.portal-parent-fader-top{位置:绝对;宽度:100%;左边距:0px;高度:36px;背景图片:线性渐变(RGBA(255,255,255,1),RGBA(255,255,255,0));z-index:50;}.Portal-Parent-Fader-Bottom{位置:绝对;宽度:100%;底部:8px;左边距:0px;高度:36px;背景图片:线性渐变(RGBA(255,255,255,0),RGBA(255,255,255,1));z索引:50;}.门户父文本{填充:$基线-高度/2;颜色:#5C6D73;z索引:40;}.portal-iframe{宽度:100%;高度:400px;}}。

同样,这不是完整的SCSS。你可以从GitHub那里得到它!

我学到的一件事是永远不要期望代码开箱即用。所以如果没有,不要生我的气!我现在已经实现了两次-一次是在我自己的网站上,另一次是在GitHub上可以找到的开箱即用的Jekyll构建上-所以我知道它是有效的。

我很乐意看到它适用于其他静态站点生成器。此外,我有一些改进的想法,比我想出来的更好的开发人员。我不能付任何钱,但你会赢得荣誉和荣耀。

启用有界滚动。理想情况下,读者应该能够探索被引用的上下文,而不是疯狂地滚动到窗口顶部。能够上下滚动几百个像素将是超级强大的。

突出显示报价。特别是如果启用了有限滚动,自动突出显示引用部分将会很酷。2020年3月5日更新:Twitter用户@in_McDonalds已经实现了这一点!非常感谢!

基于引用线段长度的可变高度。通过指定引用段的开始和结束,此建议和上述建议可能会奏效。

提高效率。如果有人能想出如何用更少的代码来做到这一点,那么一定要提出一个拉请求。

这就是事情的全部。这很简单,但我认为这很酷,而且是一种更具网络原生性的区块引用方式。如果您在您自己的站点上实现它,请将其发送给我,我很乐意在此页面上介绍您的实现。

对于这样的项目,我将给您留下一些最后的想法。

我不知道这件事是否会被采用,但原则上讲,在开放设计和UX模式上工作会产生很大的价值。套用LOT2046实践代码,并不是每一行代码或特性都值得拥有自己的公司。如果我们坚持扭曲每一个好的想法以适应企业媒介,我们将永远看不到我们想要的未来实现。就这么简单。我希望看到更多的设计师为公众工作,并以这种方式定位创意。

网络仍然是一种非常年轻的媒体,它受到印刷媒体设计的影响比其他任何东西都要大。与今天相比,屏幕上的文本可以做的事情要多得多。引用,绘画,聊天,语音到文本。机会无处不在,门槛也很低!如果我们真的想要释放知识的价值,我们应该考虑如何改进知识生产堆栈的每一个部分,包括阅读。正如劳雷尔·施武斯特(Laurel Schwulst)所说:“富有想象力的功能很重要,即使它只是过去的痕迹,因为它仍然是一个更理想世界的草图。”