语法高亮库基础原理

在研究使用能够在web页面上代码语法高显的解决方案时,发现有很多现成的开源库。比较中意的有prism.js,highlightjs。他们的原理基本上核心就两点:

1. 利用html的<pre>特性:即原封不动显示code

2. 针对不同源代码其语法结构特点,设计该语言的正则匹配规则集。库代码将针对待高显的源代码做正则匹配,形成新的显示内容,该内容由浏览器在<pre>元素中原样展示

在试用prism或者highlightjs时,简单的css代码可以非常方便的工作,但是当我试着高显c语言代码时,就发生问题了。prism.js会将<stdlib.h>整个剔除。

最后研究下来,原因是和这类基于正则的语法高亮的基石头--pre元素的工作机制有关.解决方案就是必须在加载含html entity的代码之前必须做 转换,比如  < 就翻译为 &lt; 这样pre元素就无法将其解析为html markup,而是解析为 < 这个字符来显示。 为了满足我的好奇心,我再继续深挖下去:

https://www.sitepoint.com/everything-need-know-html-pre-element/

<pre>是怎么工作的?

html的pre元素是一个简单而又有语意的显示"格式化内容"的方式,比如显示源代码。

在html document中,pre元素代表着"preformatted text".这意味着你的tab缩进,多空格,新转行标识等其他编排格式将被原封保留,而不是像普通html元素一样将多个space空格合并。。

默认情况下,浏览器在渲染pre元素的内容时使用"单空格"或者说 固定长度 的字体。

如果你将上面的内容放到一个其他的非pre元素中,则所有的额外空格,new lines,以及缩进格式都将被忽略。因此虽然你的代码为这个样子:

<div>
Jack: Hello. How are you?
Jill: I'm great. Thanks for asking.
</div>

但是浏览器却渲染成:

Jack: Hello. How are you? Jill: I'm great. Thanks for asking.

但是,如果我们把上面的html代码放到pre元素中,

<pre>
Jack: Hello. How are you?
Jill: I'm great. Thanks for asking.
</pre>

将会渲染成:

正确地marking up source code

如上面描述,pre元素用于那些具有能够影响内容的真实含义的排版格式的文本,比如源代码,艺术字体等。

如果你想在html document中渲染一块而不是一行源代码,你应该使用一个code 元素包含代码并且嵌入在pre元素中。这是有语意的,对于搜索引擎尤为重要,因为这将告诉搜索引擎,code中是计算机源代码,而非文档内容

我们来看一下语意化地构建一段javascript代码:

<pre><code>// Logs &quot;Hello World!&quot;
// in the browser's developer console
console.log(&quot;Hello World!&quot;);</code></pre>

使用内嵌在pre元素中的html的元素

在pre元素中,如果你不将内容进行escape,这时,如果内容出现html标签比如<h1>则浏览器会以html元素的普通渲染方式只渲染其tag中的内容,而不会将<h1>作为普通的文本进行显示!!!

正因为如此,

1. 如果你希望将内容作为源代码原封不动显示,则必须escape <,"等html entity;

2. 如果你希望使用h1标签进行格式化pre中的源代码,则你不能escape <,"等html entity

我们看以下例子,在html中,em和strong元素用于格式化其内嵌文本的:

从上面的实例可以看出,针对语法高亮显示这个需求,我们可以借用highlight.js或者prism.js对于源代码进行格式化,通过增加不同的html tag并作相应的css styling来实现不同语法部分的高亮显示!!同时又能够保持源代码的格式输出不变

常见问题

overflows

如果pre元素中的text比较长,超过了pre元素的宽度,这时有以下解决方案:

1. pre增加overflow auto,实现自动加一个滚动条

pre {
overflow: auto;
}

2.pre增加white-space: pre-wrap实现转行

pre {
white-space: pre-wrap;
}

我比较倾向于第一个方案,因为这忠实地反映了原内容的格式

渲染html源代码

正如前面提到过的,在pre元素中可以内嵌html来做css格式调整,但是如果希望在pre元素中原封不动地展示html代码,又该怎么办呢?

答案就是escape那些html预留的字符.这些字符被称为html entity.核心的就是<,>,",详细的html entity列表你可以在这里查看:

https://dev.w3.org/html5/html-author/charref

实际上即便是c语言代码,也存在着类似问题,究其原因是比如 #inclue <stdio.h>这一个代码,其中包含了< 这个tag起始,而highlightjs或者prismjs将无法正确处理,一个比较好的办法是使用一个plugin,在正式pattern matching之前做escape操作就好了

markup最佳实践

<pre><code>Line 1 (first line)
Line 2
Line 3
Line 4 (last line)</code></pre>

如果不遵循以上最佳实践,可能带来的问题是浏览器可能会自动给你错位

代码语法高亮踩坑-原理,问题, PRE元素及htmlentity的更多相关文章

  1. [转]Haroopad Markdown 编辑器代码语法高亮支持

    代码语法高亮 书写格式为: ` ` ` language_key if (condition){ return true } ` ` ` 在 ` ` ` (三个反引号)之间的是代码,其中languag ...

  2. phpBB论坛 代码 语法高亮 模块 Codebox Plus

    phpBB代码语法高亮模块 Codebox Plus Code-By.Org (https://www.phpbb.com/customise/db/mod/codebox_plus/) (https ...

  3. Android 代码编辑器中实现代码语法高亮

    想写一款Android手机上的代码编辑器,实现类似c4droid中代码语法高亮 通过Android中的控件WebView中嵌入html网页,html引入CodeMirror这个第三方库就可以了,其实就 ...

  4. 怎样在WPS上实现代码语法高亮

    转载自:http://www.cnblogs.com/yuphone/archive/2009/12/13/1622901.html 小時不識月 Stupid & Hungry 本文列举两种可 ...

  5. [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼

    目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...

  6. [代码修订版] Python 踩坑之旅进程篇其五打不开的文件

    目录 1.1 踩坑案例 1.2 填坑和分析 1.2.1 从程序优化入手 1.2.2 从资源软硬限入手 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: ...

  7. github webhook 实现代码自动部署 踩坑!! 附加git&coding webhook部署代码

    踩坑: 1.php程序执行linux命令是以webserver的user用户(如apache .www……)操作的,需要在/etc/sudoers添加用户免密码操作权限; %apache ALL=(A ...

  8. async语法升级踩坑小记

    从今年过完年回来,三月份开始,就一直在做重构相关的事情. 就在今天刚刚上线了最新一次的重构代码,希望高峰期安好,接近半年的Node.js代码重构. 包含从callback+async.waterfal ...

  9. seg代码配置的踩坑记录

    01. SEGMENTATION FAULT 正在配置OCNET的代码,在自己的本地运行没有任何问题,但是在服务器上一直报错:SEGMENTATION FAULT 这属于很概括的报错,无法直接看明白到 ...

随机推荐

  1. 对Quene中的队列的状态进行操作

    查看队列的状态(包括队列的满状态.空.元素个数等等) import multiprocessing quene = multiprocessing.Queue(3) quene.put(12) que ...

  2. Centos7安装elasticSearch6

                                                    Elasticsearch6.0 1.Elasticsearch: Elasticsearch是一个基于 ...

  3. jersey实现RESTful接口PUT方法JSON数据传递

    项目中使用的是org.json包 maven中的配置如下: xml <!-- https://mvnrepository.com/artifact/org.json/json --> &l ...

  4. pytest文档30-功能用例与自动化用例完美对接(allure)

    前言 做自动化做久了,经常会思考一个问题,到底别人是怎么做的自动化,跟自己的有啥不一样,看过不少书和资料,都是停留在demo的层面. 真正把自动化做的好的大牛又不屑于分享自己的劳动成果,所以大部分情况 ...

  5. 201871010112-梁丽珍《面向对象程序设计(java)》第十四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. 201871010134-周英杰《面向对象程序设计(java)》第八周学习总结

    201871010134-周英杰<面向对象程序设计(java)>八周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个 ...

  7. Tools分类随笔链接整理贴(不定期更新)

    1.编程开发工具 Vs2012安装介绍   https://www.cnblogs.com/fzxiaoyi/p/12041854.html Vs2012帮助文档安装介绍  https://www.c ...

  8. iptables防火墙的基本应用

    iptables是Linux上常用的防火墙软件,下面说一下iptables的安装.清除iptables规则.iptables只开放指定端口.iptables屏蔽指定ip.ip段及解封.删除已添加的ip ...

  9. LeetCode 51. N-QueensN皇后 (C++)(八皇后问题)

    题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...

  10. CF306C White, Black and White Again

    CF306C White, Black and White Again 洛谷评测传送门 题目描述 Polycarpus is sure that his life fits the descripti ...