代码语法高亮踩坑-原理,问题, 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 这属于很概括的报错,无法直接看明白到 ...
随机推荐
- 5. [mmc subsystem] mmc core(第五章)——card相关模块(mmc type card)
零.说明(重要,需要先搞清楚概念有助于后面的理解) 1.mmc core card相关模块为对应card实现相应的操作,包括初始化操作.以及对应的总线操作集合.负责和对应card协议层相关的东西. 这 ...
- C# 上传本地视频到七牛云服务器
第一步添加DLL引用 Install-Package Newtonsoft.Json Install-Package Qiniu #region 七牛云视频上传 /// <summary> ...
- 【java集合总结】-- ArrayList源码解析
一.前言 要想深入的了解集合就必须要通过分析源码来了解它,那如何来看源码,要看什么东西呢?主要从三个方面: 1.看继承结构 看这个类的继承结构,处于一个什么位置,不需要背记,有个大概的感觉就可以,我自 ...
- Quantization aware training 量化背后的技术——Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference
1,概述 模型量化属于模型压缩的范畴,模型压缩的目的旨在降低模型的内存大小,加速模型的推断速度(除了压缩之外,一些模型推断框架也可以通过内存,io,计算等优化来加速推断). 常见的模型压缩算法有:量化 ...
- 1.编译chromium
1. 前言 做了两年Chromium相关的开发,最近项目遇到瓶颈,自己有点迷茫.回顾之前做的工作,发现对chromium的认识还停留在非常表面的水平.因此,一直想对之前做的做个总结,只有总结反思才能提 ...
- web-天下武功唯快不破
没有武术是不可摧毁的,而最快的速度是获得长期成功的唯一途径.>>>>>> ----你必须尽可能快地做到这一点!---- <<<<<&l ...
- redis常用命令手册大全
一.五种数据类型1.Redis字符串StringString 是最简单的类型,你可以理解成与 Memcached 是一模一样的类型,一个 key 对应一个value,其上支持的操作与 Memcache ...
- luoguP2260 [清华集训2012]模积和
题意 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}n\%i*m\%j*[i!=j]\) \(\sum\limits_{i=1}^{n}\sum\limits ...
- jsp中如何使用Ueditor
在jsp页面中类似word编辑器操作textarea 使用步骤: step1.官网下载Ueditor http://ueditor.baidu.com/website/download.html ...
- HttpRequest对象
在面向对象的语言中,有种“万物皆对象”的说法.在上篇文章中介绍了HttpRuntime类,在该类收到请求之后,立即通过HttpWorkerRequest工作者对象对传递的参数进行分析和分解,创建方便网 ...