如何对“哈布雷”上的代码进行正确的着色以及为什么如此困难



几个月前,我在Habré上发表了第一篇文章 。 也许有些人会注意到,尽管站点上的内置文本编辑器不支持代码的原始标记并且经常错误地突出显示其元素,但文章中的代码以不寻常的方式绘制,并且最重要的是正确着色。 同时,没有像某些完全绝望的作者那样在图片中插入代码。

就我而言,保留标记尤其重要,因为本文是对如何使用代码的描述。 为了解决该问题,我创建了一个工具 ,使您可以将所选方案中的突出显示代码从IDEA转移到有关Habr的文章。 我将讨论创建工具的过程及其使用功能。

为什么这一切


乍看起来,这似乎是出于恶作剧,仅仅是因为通过<source>标记实现的标准照明不适合。

从某种意义上说,这当然是正确的,但事实并非如此。

首先,由于没有足够的颜色信息,因此<source>的突出显示不能与代码段一起使用。 声明在作品范围之外的所有元素将被随机绘制。 这个问题没有解决方案,因为据我所知,没有一种在线着色服务允许您执行以下任一操作:

  1. 将完整的项目代码粘贴到文章中而不完整显示它,或者将链接粘贴到GitHub上的提交。 在文章的特定位置,使用完整代码中的行剪辑(带有范围指示)。 当然,在这种情况下,背光源应基于完整代码确定。
  2. 指示未定义元素的显式元信息。 对于用户来说,这是一种非常困难的方式,但是我同意这种事情。

其次, <source>的突出显示永远不会等于常规IDE中不同类型元素的数量。 并且由于上述问题,进行高级着色是没有意义的:没有人将完整的项目代码插入文章中,因此此功能将无法使用。

同时,现实情况是需要将代码段插入文章中,并且代码段越小越好。

您可以在不突出显示代码的情况下阅读代码,但是为什么呢?

哈勃的特点


IntelliJ IDEA具有将代码导出到HTML的内置支持。 定期复制代码放在剪贴板上,包括彩色代码,这些代码可以读取为HTML。

不幸的是,Habr不允许直接在文章中使用HTML标记。 造成这种情况的原因是一个漆黑的谜,但这也许是由于物品外观的统一所致。 如果您允许在文章中使用HTML,则有可能赶上进度,以免出现查看问题。

我通常支持在文章中禁止HTML的想法,但有一个警告。 对于IT专业人员而言,经常讨论代码而又无法将其正确插入文章中的资源在某种程度上是很奇怪的。

因此,我们可以使用标签<b><i><font> 。 此外,所有这些都在<code>内起作用,这是格式化所必需的。 好吧, 他们还救了我们,这对于长行代码和缩进很有用。

不用说,从IDEA获取HTML代码的所有标准方法根本都不提供这样的HTML,因此转换工作将非常庞大。

方法


首先,值得感谢作者capslocky提供有关该主题的材料 。 我没有直接使用本文中提出的工具,这种情况几乎不会发生,但是由于有了这种材料,我才了解了问题的整个深度,同时感受到了希望之风。

该出版物的唯一不足之处是大量的代码以及对其功能和原因的非常微不足道的解释。

我将尝试纠正这种情况,并描述将HTML标记添加到可插入Habr的表单中时该如何处理。

  1. 导出之前,您需要在IDEA中设置所需的配色方案,例如, 从“颜色主题”网站 。 该代码将与所选方案一起导出。 最好选择带有白色背景的方案(因为不能在Habré上设置背景)并且没有下划线。 我没想到拖动它们有多容易,因为我真的不想这么做。
  2. 我们仅使用<pre>的内部。 即使您使用的不是来自IDEA的导出,而是其他方式的导出,HTML标记中也可能会有此标记,因为没有它,就很难正确格式化代码。 标签本身被删除,将其替换为<code>
  3. 文本很可能以<span>形式显示。 他们都必须摆脱。 许多着色服务将样式添加到样式表中,这是合乎逻辑的,并使用指向样式名称的链接。 具体来说,IDEA尚未执行此操作,这使任务更加容易(样式设置直接位于<span> )。
  4. 通过<font>设置字体颜色。 不幸的是,无法设置背景色。
  5. 我们将font-style:italic属性转换为一对<i> </i>标签,并将font-weight:bold转换为<b> </b>
  6.  替换所有空格;
  7. <br>形式的换行符由\n代替。
  8. IDEA中的HTML标记从具有样式的空间中产生具有样式和空格的空行。 最好扔掉这样的样式:这将大大减少代码的长度并提高代码的可理解性。
  9. 确保换行符没有任何样式。 否则,空行会出现问题。

最后一段通过一个示例说明:

<code>
1 <font color="000000">
</font> 2
</code>

给定的代码将在12由“ Habr”翻转。 标签<b><i>以及它们的任何组合同样适用。 换行符不应具有样式,然后一切都会很好。

实作


最初,为我编写用于任意HTML代码的转换器的任务似乎相当复杂。 但是,如果您决定使用特定版本的HTML,那么一切都还不错。 我设法在纯RegExp上进行了所有操作,即使没有HTML解析也是如此。 原来的主要问题是确定“ Habr”标记的功能。

为了使换行符没有样式,我不得不进行一些棘手的替换,这可能是最难以理解的(请参见popupBr函数)。 想法是,每次替换后的标签<br>从格式化标签的深度“弹出”到外部。 因此,在所有替换之后,标签<br>的格式已过时。

此外,事实证明,IDEA不仅将Rich Text放置在剪贴板上,而且还放置了一些棘手的对象,例如application/x-java-jvm-local-objectref 。 问题是剪贴板上存在此类对象会导致控制台中关于构造DataFlavor的持续错误。 不幸的是,您无能为力:JDK仅适用于剪贴板。 对我来说,拥有这样的代码是一个发现。 显然,写这篇文章的聪明的叔叔相信它会做到的。 通常,不要担心使用该工具时可能发生的错误。

该项目是用Kotlin编写的,位于GitHub上

欢迎提出改进建议! 例如,最好将此工具设计为IDEA的插件。 我还没有找到一种简单的方法来完成此操作:不幸的是,“复制为HTML”插件的源已关闭,并且花很长时间才能弄清楚如何从头开始编写这样的插件。

Source: https://habr.com/ru/post/zh-CN472446/


All Articles