Pygments 代码中的行号在 Windows 上的 xampp 中突出显示

Posted

技术标签:

【中文标题】Pygments 代码中的行号在 Windows 上的 xampp 中突出显示【英文标题】:Line numbers in Pygments code highlight in xampp on Windows 【发布时间】:2016-04-19 00:22:57 【问题描述】:

我已在 Windows 上配置 xampp 以使用 python 2.7 和 Pygments。我的 php 代码在网站上的 Pygments 中正确突出显示。代码有颜色、span 元素、类。

看起来是这样的:

但我无法获得行号。

正如我已阅读教程,它取决于 python 脚本中的 linenos 值。该值应为tableinline1True

但这对我不起作用。我仍然给出相同的最终代码

<!doctype html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="gh.css">
</head>
<body>
<div class="highlight highlight-php"><pre><code><span class="nv">$name</span> <span class="o">=</span> <span class="s2">"Jaś"</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"Zażółć gęślą jaźń, "</span> <span class="o">.</span> <span class="nv">$name</span> <span class="o">.</span> <span class="s1">'.'</span><span class="p">;</span>
<span class="k">echo</span> <span class="s2">"hehehe@jo.io"</span><span class="p">;</span>
</code></pre></div>
</html>

如何添加行号?我把网站的两个文件放在下面:

index.py

import sys
from pygments import highlight
from pygments.formatters import HtmlFormatter

# If there isn't only 2 args something weird is going on
expecting = 2;
if ( len(sys.argv) != expecting + 1 ):
  exit(128)

# Get the code
language = (sys.argv[1]).lower()
filename = sys.argv[2]
f = open(filename, 'rb')
code = f.read()
f.close()

# PHP
if language == 'php':
  from pygments.lexers import PhpLexer
  lexer = PhpLexer(startinline=True)

# GUESS
elif language == 'guess':
  from pygments.lexers import guess_lexer
  lexer = guess_lexer( code )

# GET BY NAME
else:
  from pygments.lexers import get_lexer_by_name
  lexer = get_lexer_by_name( language )


# OUTPUT
formatter = HtmlFormatter(linenos='table', encoding='utf-8', nowrap=True)
highlighted = highlight(code, lexer, formatter)

print highlighted

index.php

<?php
define('MB_WPP_BASE', dirname(__FILE__));
function mb_pygments_convert_code($matches)

    $pygments_build = MB_WPP_BASE . '/index.py';
    $source_code = isset($matches[3]) ? $matches[3] : '';
    $class_name = isset($matches[2]) ? $matches[2] : '';

    // Creates a temporary filename
    $temp_file = tempnam(sys_get_temp_dir(), 'MB_Pygments_');

    // Populate temporary file
    $filehandle = fopen($temp_file, "w");
    fwrite($filehandle, html_entity_decode($source_code, ENT_COMPAT, 'UTF-8'));
    fclose($filehandle);

    // Creates pygments command
    $language = $class_name ? $class_name : 'guess';
    $command = sprintf('C:\Python27/python %s %s %s', $pygments_build, $language, $temp_file);

    // Executes the command
    $retVal = -1;
    exec($command, $output, $retVal);
    unlink($temp_file);

    // Returns Source Code
    $format = '<div class="highlight highlight-%s"><pre><code>%s</code></pre></div>';

    if ($retVal == 0)
        $source_code = implode("\n", $output);
    $highlighted_code = sprintf($format, $language, $source_code);
    return $highlighted_code;


// This prevent throwing error
libxml_use_internal_errors(true);

// Get all pre from post content
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding('
<pre class="php">
<code>
$name = "Jaś";
echo "Zażółć gęślą jaźń, " . $name . \'.\';
echo "<address>hehehe@jo.io</address>";
</code>
</pre>', 'HTML-ENTITIES', "UTF-8"), LIBXML_HTML_NODEFDTD);
$pres = $dom->getElementsByTagName('pre');

foreach ($pres as $pre) 
    $class = $pre->attributes->getNamedItem('class')->nodeValue;
    $code = $pre->nodeValue;

    $args = array(
        2 => $class, // Element at position [2] is the class
        3 => $code // And element at position [2] is the code
    );

    // convert the code
    $new_code = mb_pygments_convert_code($args);

    // Replace the actual pre with the new one.
    $new_pre = $dom->createDocumentFragment();
    $new_pre->appendXML($new_code);
    $pre->parentNode->replaceChild($new_pre, $pre);

// Save the HTML of the new code.
$newHtml = "";
foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $child) 
    $newHtml .= $dom->saveHTML($child);


?>
<!doctype html>
<html lang="pl">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="gh.css">
</head>
<body>
<?= $newHtml ?>
</body>
</html>

谢谢

【问题讨论】:

【参考方案1】:

在读取文件时尝试readlines:

f = open(filename, 'rb')
code = f.readlines()
f.close()

这样你会得到多行:

formatter = HtmlFormatter(linenos='table', encoding='utf-8', nowrap=True)

建议: 更多pythonic打开文件的方式是:

with open(filename, 'rb') as f:
    code = f.readlines()

就是这样,python 上下文管理器会为你关闭这个文件。

【讨论】:

感谢您的回复,吉米。当我以这种方式更改 python 脚本时,它没有帮助。所以连语法颜色都消失了。我不知道 python,但 read()readlines() 函数返回的数据类型可能不同,这可能会导致冲突。【参考方案2】:

解决了!

无包装

如果设置为 True,则根本不包装标记,甚至不在标签内。 这会禁用大多数其他选项(默认值:False)。

http://pygments.org/docs/formatters/#HtmlFormatter

【讨论】:

以上是关于Pygments 代码中的行号在 Windows 上的 xampp 中突出显示的主要内容,如果未能解决你的问题,请参考以下文章

带有行号的 Pygments HTML 表格 - 代码单元的水平滚动条

我如何使用 pygments 使降价显示行号?

Markdown 中的语法高亮显示,但选择了行号

在word中优雅地插入代码

使用 Pygments 在 Jekyll 中突出显示围栏代码块

使用 Pygments 检测代码片段的编程语言