惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
Stack Overflow Blog
Stack Overflow Blog
L
LINUX DO - 最新话题
Google Online Security Blog
Google Online Security Blog
Schneier on Security
Schneier on Security
Spread Privacy
Spread Privacy
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
S
Schneier on Security
B
Blog
The Register - Security
The Register - Security
SecWiki News
SecWiki News
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
T
Tenable Blog
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research
D
DataBreaches.Net
S
Secure Thoughts
Security Latest
Security Latest
H
Heimdal Security Blog
The Hacker News
The Hacker News
O
OpenAI News
AWS News Blog
AWS News Blog
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
腾讯CDC
U
Unit 42
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hugging Face - Blog
Hugging Face - Blog
The Last Watchdog
The Last Watchdog
Recorded Future
Recorded Future
V2EX - 技术
V2EX - 技术
爱范儿
爱范儿
F
Full Disclosure

Roy的个人站

天天在网站上填材料?简单配置,让AI替你操作 | Roy的个人站 只是组件 使用手册 | Roy的个人站 IOS常用URL Scheme整理 | Roy的个人站 Anchor 专业版手册 | Roy的个人站 MacOS在NSImage里提供了哪些系统图标 | Roy的个人站 即刻寻找果果活动技术向剧透收集 | Roy的个人站 借助amis通过json构建前端页面 | Roy的个人站 浅析Pandownload作者可能面临的责任 | Roy的个人站 实现可被链接调用的IOS应用 | Roy的个人站 避免docker挂载时产生root权限文件 | Roy的个人站 一些有关幽默的理论 | Roy的个人站 手绘一个苹果手表的动图表盘 | Roy的个人站 用markdown编写man文档 | Roy的个人站 简化scp命令文件上传下载 | Roy的个人站 PPT中使用ECharts实现可拖拽关系图 | Roy的个人站 畅言更名相关商标权的探究 | Roy的个人站 畅言PC版emoji显示 | Roy的个人站 畅言评论插件优化 | Roy的个人站
博客代码框设置换行 | Roy的个人站
2019-07-02 · via Roy的个人站

博客里的代码框一直有个问题,每行的内容太长,代码框的宽度没法完整容纳一行。网上有过加横向滚动条、鼠标移上去就代码框自动加长这两种解决方案,但都不太美观。自动换行的方案符合大部分人的习惯,于是我研究了代码框的自动换行。本文设置了一个“行号和内容分开复制、代码自动换行并不影响自动高亮”的代码框,文中有可以用的代码以及用到属性的归纳。

基础的HTML代码

博客生成的代码框,格式经过简化就是如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<figure class="highlight javascript">
<table> <tbody> <tr>
<td class="gutter">
<pre>
<span class="line">0</span><br>
<span class="line">1</span><br>
<span class="line">2</span><br>
</pre>
</td>
<td class="code">
<pre>
<span class="line">"a "<span class="keyword">very</span>" very long line"</span><br>
<span class="line">a very very long line</span><br>
<span class="line">a very very long line</span><br>
</pre>
</td>
</tr> </tbody> </table>
</figure>

这些代码均为自动生成,也没有什么可以讨论的。代码高亮通过span实现;由于代码与行号生成在两个td中,所以复制代码的时候不会复制到行号。

换行的CSS设置

换行涉及到三个内容,具体实现的代码为:

1
2
3
4
figure .code span {
white-space: pre-wrap;
word-break: break-all;
}

其中分别的作用为:

  • white-space:设置元素中的空白符如何处理
  • overflow-wrap:设置完整单词的断开方式(未用到)
  • word-break:设置完整单词(包含汉语等的句子)的断开方式

white-space

空白符的处理简而言之是这样一张表:

属性 多个换行 空格和换行 自动换行 行末空格
normal 保留一个 保留一个 移除
nowrap 保留一个 保留一个 移除
pre 保留 保留 保留
pre-wrap 保留 保留 保留不换行
pre-line 保留 保留一个 移除
break-spaces 保留 保留一个 保留换行

我们的代码,对于多个换行需要全部保留,多个空格和换行需要全部保留,需要自动换行,行末空格保留但不需要因为空白字符换行。所以就white-space的属性可以选择pre-wrap

overflow-wrap

虽然空白符处理中我们设置了需要换行,但是过长的单词还是会导致行宽超出预设的宽度。

属性 如何处理过长单词
normal 保留
break-word 断开

我们不希望因为有过长的单词导致出现横向滚动栏,所以这里可以选择break-word。但考虑到与word-break属性的作用重合,而且word-break属性更适合汉语的特别处理,所以就不再使用overflow-wrap

word-break

换行的设置也可以使用这个,这个属性可以将汉语整句视为一个单词不换行(直到有标点符号为止)。

属性 英文处理 中文处理
normal 不断开单词 断开句子
break-all 断开单词 断开句子
keep-all 不断开单词 不断开句子
break-word 可能的话不断开单词 断开句子

其中break-allbreak-word的区别为:若一行可以容纳一个单词但是无法容纳两个,break-all将断开第二个单词,break-word将把第二个单词放在第二行。

根据要求,我们就选用了break-all。这里其实和使用overflow-wrap: break-word是一样的效果。

换行的JS设置

自动换行之后就需要行号的位置根据代码的长度做相应变化,博客里本来有代码框自动调整宽度的代码,这里将行高的调整也加进去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
+function($) {
'use strict';

var CodeBlockResizer = function(elem) {
this.$codeBlocks = $(elem);
};

CodeBlockResizer.prototype = {
run: function() {
var self = this;
self.resize();
$(window).smartresize(function() {
self.resize();
});
},

resize: function() {
var self = this;
self.$codeBlocks.each(function() {
var $gutter = $(this).find('.gutter');
var $code = $(this).find('.code');

var codePaddings = $code.width() - $code.innerWidth();
var width = $(this).outerWidth() - $gutter.outerWidth() + codePaddings;

$code.css('width', width);
$code.children('pre').css('width', width);

for (var i = 0, m = $gutter.find('span').length; i < m; i++) {
$gutter.find('span').eq(i).height(
$code.find('span.line')[i].offsetHeight);
}
});
}
};

$(document).ready(function() {
$.fn.hasHorizontalScrollBar = function() {
return this.get(0).scrollWidth > this.innerWidth();
};
var resizer = new CodeBlockResizer('figure.highlight');
resizer.run();
});
}(jQuery);

这里与行号位置相关的部分就是29-32行的内容,根据offsetHeight调整height

仅是这样还是无法更改行号的位置,原因在于目前显示代码使用的都是span元素。我们若需要通过height调整行号所占的高度,应将其显示方式改为inline-block,所以增加如下CSS:

1
2
3
4
figure.highlight pre > .line {
display: inline-block;
line-height: 18px;
}

其中如果不设置display: inline-blockline-heightheight也将不相同,可能出现的小数将导致不必要的麻烦。

到这里就完成了全部关于代码换行的设置。