代码语法高亮踩坑-原理,问题, 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 这属于很概括的报错,无法直接看明白到 ...
随机推荐
- [linux] 进程五状态模型
运行态:该进程正在执行:就绪态:进程做好了准备,只要有机会就开始执行:阻塞态:进程在某些事件发生前不能执行,如I/O 操作完成:新建态:刚刚创建的进程,操作系统还没有把它加入到可执行进程组中.通常是进 ...
- adb shell提示“adb server is out of date.” 解决方法
[问题描述] 1.打开运行:window+R,输入cmd回车 2.使用命令 adb shell 无法登录安卓设备,提示如下: adb server is out of date. killing.. ...
- JS高阶---IIFE&&函数前加;
IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数. 全称为Immediately Invoked Function Expression 有时如果不加:会出现一 ...
- 201871010128-杨丽霞《面向对象程序设计(Java)》第十二周学习总结
201871010128-杨丽霞<面向对象程序设计(Java)>第十一周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...
- 认识map-reduce
基本概念 map-reduce1.0 例子: hadoop streaming 用语言驱动map-reduce的话,使用的hadoop streaming命令,可以通过python,php,java来 ...
- oracle--sqlplus格式化输出
01,日期格式化输出 SQL> alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:mi:ss'; SQL> select sysdate ...
- PS:老权限登录Action 中 WebObjManager有问题,一直登录不起问题
.ashx后面代码要多继承一个, IRequiresSessionState接口
- CentOS7 Harbor 安装
安装Harbor,首先要安装docker 和 docker-compose 1.安装docker (1)安装一些必要的系统工具 $ yum install -y yum-utils device- ...
- [数据库] SQL 语法之进阶篇
一.创建计算字段 下面介绍什么是计算字段,如何创建计算字段,以及如何从应用程序中使用别名引用它们. 1.1 计算字段 存储在数据库表中的数据一般不是应用程序所需要的格式,下面举几个例子. 需要显示公司 ...
- 在Linux上利用curl 命令模拟 HTTP GET/POST 请求
本文系转载,原文地址:https://www.cnblogs.com/alfred0311/p/7988648.html 序言 在 Linux 操作系统上对后端程序进行测试的时候,需要进行模拟连接或者 ...