html:如何将行号添加到源代码块

新手上路,请多包涵

我想以这样的方式显示带有行号的源代码:

  1. 可以复制和粘贴没有行号的代码,尊重换行符、空格和制表符。
  2. 数字是右对齐的。
  3. 代码可以环绕。

我尝试了以下方法。

有序列表

<style type="text/css">
    ol.code > li {
        white-space: pre-wrap;
    }
</style>
...
<ol class="code">
    <li>first line</li>
    <li>   indented line followed by empty line</li>
    <li></li>
    <li>the following line consists of one single space</li>
    <li> </li>
    <li>this line has a space at the end </li>
    <li>&#9;and one leading and ending tab&#9;</li>
    <li>fill to</li>
    <li>ten</li>
    <li>lines</li>
</ol>

这在大多数情况下都有效,但在复制和粘贴时,行中的前导空格和制表符不会复制到我的浏览器 (Iceweasel) 中。所以#1 用这种方法失败了。

预配计数器

<style type="text/css">
    pre.code {
        white-space: pre-wrap;
    }
    pre.code:before {
        counter-reset: listing;
    }
    pre.code code {
        counter-increment: listing;
    }
    pre.code code:before {
        content: counter(listing) ". ";
        width: 8em;         /* doesn't work */
        padding-left: auto; /* doesn't work */
        margin-left: auto;  /* doesn't work */
        text-align: right;  /* doesn't work */
    }
</style>
...
<pre class="code">
<code>first line</code>
<code>   indented line followed by empty line</code>
<code></code>
<code>the following line consists of one single space</code>
<code> </code>
<code>this line has a space at the end </code>
<code>&#9;and one leading and ending tab&#9;</code>
<code>fill to</code>
<code>ten</code>
<code>lines</code>
</pre>

这几乎可行,但#2 失败了。它有一个额外的问题,即换行在行号(左边距旁边)下继续,而不是在行开始(表格)下。

同步线和预

这是我在 https://www.sitepoint.com/best-practice-for-code-examples/ 中找到的建议,但它明确表示必须禁用换行,因此 #3 失败了。这也让我非常不安,因为我已经看到这些块在某些站点中被破坏了。

没有 JavaScript 有没有办法做到这一点?

原文由 Pedro Gimeno 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 691
2 个回答

虽然从技术上讲我的问题已经被 Rounin 回答了(谢谢),但事实是我对结果并不完全满意,因为我没有说明我认为在发布问题后很重要的其他几个必要条件,并且他们在该解决方案中失败了:

  1. 当一条线环绕时,它应该在上面的线下面,而不是在行号下面。
  2. 数字和文本列都应该是样式化的(值得注意的是,整个列的背景应该很容易改变)。

我尝试了另一个 inline-block 的解决方案,但它失败了#5,并且在调整到任何宽度时都遇到了问题。

<OL> 非常接近,但不完全在那里。 <OL> 我知道不会飞的替代方案是使用一张桌子。它不会飞,因为浏览器 需要 <PRE> 元素才能正确复制/粘贴空格和制表符。

然后突然间,我的脑海里闪过一个解决方案。强制不是表格的元素表现得像表格一样,是 table-xxxx 显示值的确切目的!

所以我们开始吧。在 Iceweasel 24.7.0 和 Chromium 35.0.1916.153 中测试。该演示包括额外的样式作为该方法多功能性的示例。

CSS:

 /* Bare bones style for the desired effect */
pre.code {
    display: table;
    table-layout: fixed;
    width: 100%; /* anything but auto, otherwise fixed layout not guaranteed */
    white-space: pre-wrap;
}
pre.code::before {
    counter-reset: linenum;
}
pre.code span.tr {
    display: table-row;
    counter-increment: linenum;
}
pre.code span.th { /* used for line numbers */
    display: table-cell;
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;
}
pre.code span.th::before {
    content: counter(linenum);
    text-align: right;
    display: block;
}
pre.code span.th {
    width: 4em; /* or whatever the desired width of the numbers column is */
}
pre.code code {
    display: table-cell;
}

和 HTML:

 <pre class="code">
<span class="tr first-row"><span class="th"></span><code>   indented line</code></span>
<span class="tr"><span class="th"></span><code>unindented line</code></span>
<span class="tr"><span class="th"></span><code>&#9;line starting and ending with tab&#9;</code></span>
<span class="tr"><span class="th"></span><code></code></span>
<span class="tr"><span class="th"></span><code>the above line should be empty</code></span>
<span class="tr"><span class="th"></span><code>overlong line that wraps around or so I hope because it's really long and should overflow the right sided margin of the web page in your browser</code></span>
<span class="tr"><span class="th"></span><code>fill up to ten</code></span>
<span class="tr"><span class="th"></span><code>lines to check</code></span>
<span class="tr"><span class="th"></span><code>alignment</code></span>
<span class="tr"><span class="th"></span><code>of numbers</code></span>
</pre>

带有额外样式的演示

更新:自从我发布了这个问题,了解到 GeSHi 语法荧光笔有一个使用以下模式的选项,它也满足所有要求,并且对于那些对表格过敏的人来说可能更容易接受:

 <ol>
  <li><pre>code</pre></li>
  <li><pre>code</pre></li>
  <li><pre>...</pre></li>
</ol>

原文由 Pedro Gimeno 发布,翻译遵循 CC BY-SA 4.0 许可协议

您需要将 display: inline-block 添加到您的 ::before 伪元素:

例如。

 pre.code code::before {
  content: counter(listing) ". ";
  display: inline-block;
  width: 8em;
  padding-left: auto;
  margin-left: auto;
  text-align: right;
}

然后你所有的其他风格都会起作用。


Explanation: By default, ::before and ::after pseudo-elements have a display style of inline .

You need to explicitly declare a display style of block or inline-block if you want to start setting width , text-align 等等


例子:

 pre.code {
  white-space: pre-wrap;
}
pre.code::before {
  counter-reset: listing;
}
pre.code code {
  counter-increment: listing;
}
pre.code code::before {
  content: counter(listing) ". ";
  display: inline-block;
  width: 8em;         /* now works */
  padding-left: auto; /* now works */
  margin-left: auto;  /* now works */
  text-align: right;  /* now works */
}
 <pre class="code">
<code>first line</code>
<code>   indented line followed by empty line</code>
<code></code>
<code>the following line consists of one single space</code>
<code> </code>
<code>this line has a space at the end </code>
<code>&#9;and one leading and ending tab&#9;</code>
<code>fill to</code>
<code>ten</code>
<code>lines</code>
</pre>

添加: 另一种 CSS 方法使用 floatsclears 这意味着当换行时,它们不会换行在行号下面:

 pre.code {
  white-space: pre-wrap;
  margin-left: 8em;
}

pre.code::before {
  counter-reset: listing;
}

pre.code code {
  counter-increment: listing;
  text-align: left;
  float: left;
  clear: left;
}

pre.code code::before {
  content: counter(listing) ". ";
  display: inline-block;
  float: left;
  height: 3em;
  padding-left: auto;
  margin-left: auto;
  text-align: right;
}

原文由 Rounin - Standing with Ukraine 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏