0

I have configured xampp on windows to work with python 2.7 and Pygments. My php code is highlighted properly in Pygments on the website. The code has colors, span elements, classes.

That is how it looks:

enter image description here

But I cannot get line numbers.

As I have read tutorials it depends on the linenos value in python script. The value should be either table or inline or 1 or True.

But it does not work for me. I still gives the same final code

<!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>

How to add line numbers? I put two files of the website below:

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>

Thank you

trzczy
  • 1,325
  • 2
  • 18
  • 43

2 Answers2

0

While reading the file try readlines:

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

This way you do the following it will get multiple lines :

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

Suggestion: More pythonic way of opening files is :

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

That's it python context manager closes this file for you.

Jimmy
  • 55
  • 3
  • Thank you for the reply, Jimmy. When I changed the python script in that way it did not help. So even syntax colors disappeared. I do not know python but the data type of that `read()` and `readlines()` functions return might differ and that could cause a conflict. – trzczy Apr 19 '16 at 11:19
0

Solved!

nowrap

If set to True, don’t wrap the tokens at all, not even inside a tag. This disables most other options (default: False).

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

trzczy
  • 1,325
  • 2
  • 18
  • 43