scrivo / highlight.php

A port of highlight.js by Ivan Sagalaev to PHP
BSD 3-Clause "New" or "Revised" License
695 stars 45 forks source link

Adds a line break after comments #20

Closed ghost closed 6 years ago

ghost commented 6 years ago

Pretty much what the title says. Works perfectly except that it adds a line break after comments when there isn't any in the original code.

allejo commented 6 years ago

To help us reproduce this, could you help us out with the following information:

ghost commented 6 years ago

From my initial tests, PHP and JS (possibly all languages which support // comments).

Input

// FileComponent Class
export class FileComponent {
    file = { name: 'logo.svg', size: 2120109, type: 'image/svg' };
}

Output

// FileComponent Class

export class FileComponent {
    file = { name: 'logo.svg', size: 2120109, type: 'image/svg' };
}
allejo commented 6 years ago

Any chance you're working on Windows (there could be some weird line ending behavior)? This is what I'm getting on macOS and can't seem to reproduce the line break from your example.

<?php

require_once("../Highlight/Autoloader.php");
spl_autoload_register("Highlight\\Autoloader::load");

$js = <<<EOL
// FileComponent Class
export class FileComponent {
    file = { name: 'logo.svg', size: 2120109, type: 'image/svg' };
}
EOL;

$php = <<<EOL
<?php

// Some class
class Toast {
    // @var bool
    public butter;
}
EOL;

use Highlight\Highlighter;

$hl = new Highlighter();

$output = $hl->highlight('js', $js);
echo "<pre><code>" . $output->value . "</code></pre>";

echo "<hr>";

$output = $hl->highlight('php', $php);
echo "<pre><code>" . $output->value . "</code></pre>";

Output

// FileComponent Class
export class FileComponent {
    file = { name: 'logo.svg', size: 2120109, type: 'image/svg' };
}

---

<?php

// Some class
class Toast {
    // @var bool
    public butter;
}
ghost commented 6 years ago

Nope on macOS High Sierra. If you want I could get the site setup somewhere today and give you access?

allejo commented 6 years ago

If you execute the code snippet I posted, do you get the extra line breaks?

I’d prefer the relevant code to reproduce this issue so I could investigate/debug locally and not have to work on a remote machine. But my email is on my GH profile so feel free to send me anything there 👍

ghost commented 6 years ago

Weird if I execute your code it works fine, but I just can't see a reason it would be doing it in mine. It even goes away if I change the language to something like HTML, then comes back again if I change it to PHP or JS even though it's the same input string.

I'm still setting up my test dev, but the relevant code is...

Template

// get_sub_field('code') returns the previously mentioned string
<?php $highlighter = new Highlighter(); ?>
<pre class="o-codeBlock__content"><code><?php echo $highlighter->highlight(get_sub_field('language')['value'], get_sub_field('code')); ?></code></pre>

highlighter plugin

<?php

    class Highlighter {
        private $instance;

        /**
         * Autoload the files and create our instance
         */
        public function __construct() {
            require_once("highlight/Highlight/Autoloader.php");
            spl_autoload_register("Highlight\\Autoloader::load");
            $this->instance = new Highlight\Highlighter();
        }

        /**
         * Takes a language and content string and highlights the code
         *
         * @param string $language
         * @param string $content
         * @return string
         */
        public function highlight(string $language, string $content): string {
            return $this->instance->highlight($language, $content)->value;
        }
    }
allejo commented 6 years ago

Could it be that get_sub_field() function is manipulating the returned code snippet somehow?

Code Snippet

<?php
// this is your Highlighter wrapper
include "Highlighter.php";

function get_sub_field($field) {
    if ($field === "language") {
        return [
            "value" => "js"
        ];
    }
    elseif ($field === "code") {
        return <<<EOL
// FileComponent Class
export class FileComponent {
    file = { name: 'logo.svg', size: 2120109, type: 'image/svg' };
}
EOL;
    }
}
?>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">

// get_sub_field('code') returns the previously mentioned string
<?php $highlighter = new Highlighter(); ?>
<pre class="o-codeBlock__content"><code><?php echo $highlighter->highlight(get_sub_field('language')['value'], get_sub_field('code')); ?></code></pre>

Output

image

ghost commented 6 years ago

Doesn't look like it, if I echo out get_sub_field() by itself then there isn't a line break, it's only when I use highlight and set the language to JS or PHP that it appears, like I say it even goes if I change the language to HTML.

ghost commented 6 years ago

I think I see what the issue is, what's returned by get_sub_field() is...

// FileComponent Class\r\n
<...>

But what highlight changes it to is (removing unnecessary classes)...

<span>// FileComponent Class\r</span>\n

The \r should be outside of the span, if I manually move it outside then it displays correctly.

allejo commented 6 years ago

I can confirm that \r\n causes the extra line breaks, didn't think those would exist on macOS but Windows would be affected.

Until this is fixed, you can standardize your line endings before feeding it into Highlighter like so:

<?php $code = preg_replace('/\R/', "\n", get_sub_field('code')) ?>
<pre class="o-codeBlock__content"><code><?php echo $highlighter->highlight(get_sub_field('language')['value'], $code); ?></code></pre>
allejo commented 6 years ago

@KeironLowe92 give PR #21 a try; it should fix the issue for you.