代码语法高亮踩坑-原理,问题, 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 这属于很概括的报错,无法直接看明白到 ...
随机推荐
- hexo笔记
目录 hexo 常用指令 站内文章跳转 hexo安装 NexT主题 默认主题 评论插件-gitalk 修改内容区宽度 添加文章阴影 文章摘要设置 一篇文章多个 categories hexo的一些配置 ...
- 渗透技巧——Windows系统的帐户隐藏
渗透技巧——Windows系统的帐户隐藏 2017-11-28-00:08:55 0x01 帐户隐藏的方法 该方法在网上已有相关资料,本节只做简单复现 测试系统:·Win7 x86/WinXP 1. ...
- 基于Anaconda编译caffe+pycaffe+matcaffe in Ubuntu[不用sudo权限]
目录 caffe 编译 环境 github下载caffe源码 依赖 修改源码的编译配置 报错 测试使用 pycaffe caffe matcaffe caffe 编译 环境 Ubuntu16.04 C ...
- 浅析struct device结构体
device结构体:设备驱动模型中的基础结构体之一 struct device { /*设备所依附的父设备 大多数情况下,这样的设备是某种总线或主控制器 如果该成员变量的值为NULL,表示当前设备是一 ...
- JDOJ 1790: 高精度A-B
JDOJ 1790: 高精度A-B JDOJ传送门 洛谷 P2142 高精度减法 洛谷传送门 题目描述 高精度减法 输入格式 两个整数a,b(第二个可能比第一个大) 输出格式 结果(是负数要输出负号) ...
- JAVA基础概念(二)
一.java修饰符和使用场景 修饰符是用来定义类.方法或者变量的访问权限,分为两大类: 访问修饰符: 限定类.属性.方法是否可以被程序里其他部分访问和调用. private<default< ...
- Flask-Login中装饰器@login_manager.user_loader的作用及原理
Flask-Login通过装饰器@login_required来检查访问视图函数的用户是否已登录,没有登录时会跳转到login_manager.login_view = 'auth.login'所注册 ...
- js判断超过几个字符后显示省略号
- 在 Asp.Net Core 中安装 MVC
在 ASP.NET Core 中安装 MVC 到目前为止,我们在本系列视频中使用的 ASP.NET Core 项目是使用“空”项目模板生成的.目前这个项目没有设置和安装 MVC. 两个步骤学会在 AS ...
- canal
https://github.com/alibaba/canal/wiki/QuickStart https://github.com/alibaba/canal/releases/download/ ...