html:如何在源代码块

时间:2016-12-23 19:16:03

标签: html css

我希望以下列方式显示包含行号的源代码:

  1. 可以复制和粘贴代码,不包含行号,尊重换行符,空格和制表符。
  2. 这些数字是对的。
  3. 代码可以回滚。
  4. 我尝试了以下方法。

    有序列表

    <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以这种方法失败了。

    Pre with counter

    <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

3 个答案:

答案 0 :(得分:9)

您需要将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;
}

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

说明:默认情况下,::before::after个伪元素的display样式为inline

如果您想开始设置displayblock等,则需要明确声明inline-block样式的widthtext-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;         /* doesn't work */
  padding-left: auto; /* doesn't work */
  margin-left: auto;  /* doesn't work */
  text-align: right;  /* doesn't work */
}
<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>

已添加: 使用floatsclears的替代CSS方法,这意味着当换行时,它们不会包含在行号下面:

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;
}

答案 1 :(得分:2)

我建议使用codemirror来执行此操作,而不是自己编写。

您可以免费获得您描述的功能以及许多其他很棒的功能:

https://codemirror.net/doc/manual.html#usage

CodeMirror.fromTextArea(document.getElementById("myDiv"), {
    lineNumbers: true,
    mode: "htmlmixed"
  });

答案 2 :(得分:2)

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

  1. 当一条线缠绕时,它应该位于上面一行的下方,而不是在行号下面。
  2. 数字和文本列都应该是样式的(特别是整个列的背景应该很容易更改)。
  3. 我尝试了另一个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>
    

    Demo with extra styling