代码语法高亮踩坑-原理,问题, PRE元素及htmlentity
语法高亮库基础原理
在研究使用能够在web页面上代码语法高显的解决方案时,发现有很多现成的开源库。比较中意的有prism.js,highlightjs。他们的原理基本上核心就两点:
1. 利用html的<pre>特性:即原封不动显示code
2. 针对不同源代码其语法结构特点,设计该语言的正则匹配规则集。库代码将针对待高显的源代码做正则匹配,形成新的显示内容,该内容由浏览器在<pre>元素中原样展示
在试用prism或者highlightjs时,简单的css代码可以非常方便的工作,但是当我试着高显c语言代码时,就发生问题了。prism.js会将<stdlib.h>整个剔除。


最后研究下来,原因是和这类基于正则的语法高亮的基石头--pre元素的工作机制有关.解决方案就是必须在加载含html entity的代码之前必须做 转换,比如 < 就翻译为 < 这样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 "Hello World!"
// in the browser's developer console
console.log("Hello World!");</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的更多相关文章
- [转]Haroopad Markdown 编辑器代码语法高亮支持
代码语法高亮 书写格式为: ` ` ` language_key if (condition){ return true } ` ` ` 在 ` ` ` (三个反引号)之间的是代码,其中languag ...
- phpBB论坛 代码 语法高亮 模块 Codebox Plus
phpBB代码语法高亮模块 Codebox Plus Code-By.Org (https://www.phpbb.com/customise/db/mod/codebox_plus/) (https ...
- Android 代码编辑器中实现代码语法高亮
想写一款Android手机上的代码编辑器,实现类似c4droid中代码语法高亮 通过Android中的控件WebView中嵌入html网页,html引入CodeMirror这个第三方库就可以了,其实就 ...
- 怎样在WPS上实现代码语法高亮
转载自:http://www.cnblogs.com/yuphone/archive/2009/12/13/1622901.html 小時不識月 Stupid & Hungry 本文列举两种可 ...
- [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...
- [代码修订版] Python 踩坑之旅进程篇其五打不开的文件
目录 1.1 踩坑案例 1.2 填坑和分析 1.2.1 从程序优化入手 1.2.2 从资源软硬限入手 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: ...
- github webhook 实现代码自动部署 踩坑!! 附加git&coding webhook部署代码
踩坑: 1.php程序执行linux命令是以webserver的user用户(如apache .www……)操作的,需要在/etc/sudoers添加用户免密码操作权限; %apache ALL=(A ...
- async语法升级踩坑小记
从今年过完年回来,三月份开始,就一直在做重构相关的事情. 就在今天刚刚上线了最新一次的重构代码,希望高峰期安好,接近半年的Node.js代码重构. 包含从callback+async.waterfal ...
- seg代码配置的踩坑记录
01. SEGMENTATION FAULT 正在配置OCNET的代码,在自己的本地运行没有任何问题,但是在服务器上一直报错:SEGMENTATION FAULT 这属于很概括的报错,无法直接看明白到 ...
随机推荐
- 如何下载windows版的kubectl.exe文件
github上的下载链接,不能直接下载. https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#client-b ...
- 201871010102-常龙龙《面向对象程序设计(java)》第七周学习总结
二.博文正文开头格式: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/ ...
- 201871010110-李华《面向对象程序设计(java)》第十一周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- CF1256(div3 java题解)
A: 题意:给定A个N元,B个一元,问是否可以凑成S元. 思路:A*i+j=S 即 A*I<=S<=A*I+B 即min(S/N,A)+B>=S: /* @author nimphy ...
- JVM-卡表(Card Table)
简介 现代JVM,堆空间通常被划分为新生代和老年代.由于新生代的垃圾收集通常很频繁,如果老年代对象引用了新生代的对象,那么,需要跟踪从老年代到新生代的所有引用,从而避免每次YGC时扫描整个老年代,减少 ...
- JDOJ 1044 Span
JDOJ 1044 Span https://neooj.com/oldoj/problem.php?id=1044 Description 某国有N个村子,M条道路,为了实现“村村通工程”现在要”油 ...
- Autofac注册组件详解
注册概念:我们通过创建 ContainerBuilder 来注册 组件 并且告诉容器哪些 组件 暴露了哪些 服务.组件 可以通过 反射 创建; 通过提供现成的 实例创建; 或者通过 lambda 表达 ...
- 【CF1097F】Alex and a TV Show
[CF1097F]Alex and a TV Show 题面 洛谷 题解 我们对于某个集合中的每个\(i\),令\(f(i)\)表示\(i\)作为约数出现次数的奇偶性. 因为只要因为奇偶性只有\(0, ...
- [LeetCode] 592. Fraction Addition and Subtraction 分数加减法
Given a string representing an expression of fraction addition and subtraction, you need to return t ...
- 关于交叉编译Nodejs的坑
前言 交叉编译Nodejs到其他平台上的时候,遇到了2个坑,网上极少有人提及,花了整个晚上才解决,在此记录下. 我的编译目标环境为: 龙芯3A 编译脚本 cd 代码目录 export PREFIX=/ ...