Skip to content

Syntax highlighter cleanup #1352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
be338ed
don't allow classes to be passed through on pod html
haarg Sep 26, 2014
d4a64fb
icons for source view
haarg Sep 16, 2014
2365aaf
move syntax highlighter code to separate file
haarg Sep 15, 2014
06caa48
use long filetype names for syntax brushes
haarg Sep 15, 2014
5e88468
improve module regex in syntax highlighter
haarg Sep 16, 2014
124d73c
initialize syntax highlighter with real classes and data attributes
haarg Sep 15, 2014
dd8dcc6
use normal pre styles for syntax highlighter
haarg Sep 15, 2014
faac8b4
hide/show pod by class toggle
haarg Sep 16, 2014
718f00c
provide pod lines via data attribute rather than javascript
haarg Sep 16, 2014
59d0329
add line numbers after highlighting rather than monkey patching
haarg Sep 16, 2014
9f78c09
use hide/show labels for pod toggle
haarg Sep 16, 2014
d2d1fd5
allow highlighting multiple lines
haarg Sep 16, 2014
d25f102
only link line numbers on source page
haarg Sep 16, 2014
f37119d
scroll to highlighted element for ranges too
haarg Sep 16, 2014
8911ac1
auto-hide pod via class attribute
haarg Sep 16, 2014
cfbcdfe
re-highlight rows when location hash changes
haarg Sep 16, 2014
b6dc99c
don't scroll when clicking on line numbers
haarg Sep 16, 2014
7ac339e
allow syntax highlighter config through HTML filter
haarg Sep 17, 2014
34bbf5a
move duplicate regex into variable
haarg Sep 22, 2014
cfba3bf
prevent syntax highlighter from stripping leading tabs as well
haarg Sep 22, 2014
b5cd942
simplify and reduce duplication in syntax highlighter code
haarg Sep 22, 2014
d3d4d21
more comments in syntax highlighter code
haarg Sep 22, 2014
6746cd7
tidy pod html filter config
haarg Sep 26, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app.psgi
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ my @js_files = map {"/static/js/$_.js"} (
bootstrap/bootstrap-tooltip
bootstrap/bootstrap-affix
bootstrap-slidepanel
syntaxhighlighter
),
);
my @css_files
Expand Down
33 changes: 20 additions & 13 deletions lib/MetaCPAN/Web/Controller/Pod.pm
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ sub view : Private {
br => [],
caption => [],
center => [],
code => [],
code => [ { class => qr/^language-\S+$/ } ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you comment on what values might be coming through this attribute and from where?
I don't see why we should allow the class attribute to come through from pod for any tag.

dd => ['id'],
div => [qw(id style)],
dl => ['id'],
Expand All @@ -125,18 +125,25 @@ sub view : Private {
img => [qw( alt border height width src style title / )],
li => ['id'],
ol => [],
p => [qw(class style)],
pre => [qw(id class style)],
span => [qw(style)],
strong => [],
sub => [],
sup => [],
table => [qw( style class border cellspacing cellpadding align )],
tbody => [],
td => [qw(style class)],
tr => [qw(style class)],
u => [],
ul => ['id'],
p => [qw(style)],
pre => [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you comment on where these data attributes come from and/or what they mean?
If they're only added by javascript then we shouldn't need them here.

qw(id style),
{
class => qr/^line-numbers$/,
'data-line' => qr/^\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*$/,
'data-start' => qr/^\d+$/,
}
],
span => [qw(style)],
strong => [],
sub => [],
sup => [],
table => [qw( style border cellspacing cellpadding align )],
tbody => [],
td => [qw(style)],
tr => [qw(style)],
u => [],
ul => ['id'],
}
);

Expand Down
8 changes: 4 additions & 4 deletions lib/MetaCPAN/Web/Controller/Source.pm
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ sub detect_filetype {
local $_ = $file->{path};

# No separate pod brush as of 2011-08-04.
return 'pl' if /\. ( p[ml] | psgi | pod ) $/ix;
return 'perl' if /\. ( p[ml] | psgi | pod ) $/ix;

return 'pl' if /^ cpanfile $/ix;
return 'perl' if /^ cpanfile $/ix;

return 'yaml' if /\. ya?ml $/ix;

return 'js' if /\. js(on)? $/ix;
return 'javascript' if /\. js(on)? $/ix;

return 'c' if /\. ( c | h | xs ) $/ix;

Expand All @@ -97,7 +97,7 @@ sub detect_filetype {
if ( defined( $file->{mime} ) ) {
local $_ = $file->{mime};

return 'pl' if /perl/;
return 'perl' if /perl/;
}

# Default to plain text.
Expand Down
2 changes: 1 addition & 1 deletion root/diff.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
<div class="diff-header">
<a href="/source/<% diff.target %>/<% file.path %>"><% file.path %></a>
</div>
<pre class="brush: diff; class-name: 'highlight'; toolbar: false; gutter: false" id="source"><% parts = file.diff.split("\n"); WHILE parts; line = parts.shift; LAST IF line.match( '^\+' ); END; parts.join("\n") %></pre>
<pre><code class="language-diff"><% parts = file.diff.split("\n"); WHILE parts; line = parts.shift; LAST IF line.match( '^\+' ); END; parts.join("\n") %></code></pre>
</div>
<% END %>
</div>
2 changes: 1 addition & 1 deletion root/pod.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
<a name="___pod"></a>
<div class="pod content anchors">
<% IF pod %>
<% pod.replace(/<pre><code>/, '<pre class="brush: pl; class-name: \'highlight\'; toolbar: false; gutter: false; metacpan-verbatim">').replace(/<\/code><\/pre>/, '</pre>') | none %>
<% pod | none %>
<% ELSIF pod_error %>
<p class="pod-error">Error rendering POD for <code><% module.name %></code> - <% pod_error %></p>
<% ELSE %>
Expand Down
31 changes: 10 additions & 21 deletions root/source.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@
<li class="nav-header">Tools</li>
<li>
<div>
<a href="/release/<% module.author %>/<% module.release %>/">Release Info</a>
<a href="/release/<% module.author %>/<% module.release %>/"><i class="fa fa-info-circle fa-fw black"></i>Release Info</a>
</div>
</li>
<% IF module.documentation %>
<li>
<div>
<a href="/pod/<% module.documentation %>">Module Documentation</a>
<a href="/pod/<% module.documentation %>"><i class="fa fa-book fa-fw black"></i>Module Documentation</a>
</div>
</li>
<% ELSIF module.slop %>
<li>
<div>
<a href="/pod/<% doc_view_url %>">Documentation View</a>
<a href="/pod/<% doc_view_url %>"><i class="fa fa-book fa-fw black">Documentation View</a>
</div>
</li>
<% END %>
<li>
<div>
<a href="/author/<% module.author %>/">Author</a>
<a href="/author/<% module.author %>"><i class="fa fa-user fa-fw black"></i>Author</a>
</div>
</li>
<li>&nbsp;</li>
<li><div><a href="<% raw_url %>">Raw code</a></div></li>
<li><div><a href="<% raw_url %>"><i class="fa fa-file-text-o fa-fw black"></i>Raw code</a></div></li>
<li>
<div>
<a href="/raw/<% module.author %>/<% module.release %>/<% module.path %>?download=1">Download</a>
<a href="/raw/<% module.author %>/<% module.release %>/<% module.path %>?download=1"><i class="fa fa-download fa-fw black"></i>Download</a>
</div>
</li>
<% IF module.sloc > 0 %>
<li><div><a href="javascript:togglePod(<% module.pod_lines.json %>)">Toggle pod</a></div></li>
<li><div><button class="btn-link pod-toggle<% IF module.sloc > 0; " pod-hidden"; END %>" onclick="togglePod()"><i class="fa fa-exchange fa-fw black"></i><span class="hide-pod">Hide</span><span class="show-pod">Show</span> Pod</button></div></li>
<% END %>
<li class="nav-header">Info</li>
<li><% module.sloc %> lines of code</li>
Expand All @@ -55,21 +55,10 @@

<div class="content">
<% IF !module.binary %>
<pre class="brush: <% filetype %>; class-name: 'highlight'; toolbar: false;" id="source"><% source %></pre>
<pre id="source" class="line-numbers pod-toggle<% IF module.sloc > 0; " pod-hidden"; END %>" data-pod-lines="<%
module.pod_lines.map(->(lines){ lines.0+1 _ "-" _ (lines.0+lines.1) }).join(', ')
%>"><code class="language-<% filetype %>"><% source %></code></pre>
<% ELSE %>
This file cannot be displayed inline. Try the <a href="<% raw_url %>">raw file</a>.
<% END %>
</div>

<script type="text/javascript">

//document.getElementById('source').style.visibility = 'hidden';
//SyntaxHighlighter.all();
$(document).ready(function() {
<% IF module.sloc > 0 %>
togglePod(<% module.pod_lines.json %>);
<% END %>
if(document.location.hash)
document.location.href = document.location.href;
});
</script>
109 changes: 0 additions & 109 deletions root/static/js/cpan.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,6 @@ $.extend({
}
});

var podVisible = false;

function togglePod(lines) {
var toggle = podVisible ? 'none' : 'block';
podVisible = !podVisible;
if (!lines || !lines.length) return;
for (var i = 0; i < lines.length; i++) {
var start = lines[i][0],
length = lines[i][1];
var sourceC = $('.container')[0].children;
var linesC = $('.gutter')[0].children;
var x;
for (x = start; x < start + length; x++) {
sourceC[x].style.display = toggle;
linesC[x].style.display = toggle;
}

}
}

function togglePanel(side) {
var panel = $('#' + side + '-panel');
var shower = $('#show-' + side + '-panel');
Expand Down Expand Up @@ -83,95 +63,6 @@ function toggleTOC() {
$(document).ready(function () {
$(".ttip").tooltip();

SyntaxHighlighter.defaults['quick-code'] = false;
SyntaxHighlighter.defaults['tab-size'] = 8;

// Allow tilde in url (#1118). Orig: /\w+:\/\/[\w-.\/?%&=:@;#]*/g,
SyntaxHighlighter.regexLib['url'] = /\w+:\/\/[\w-.\/?%&=:@;#~]*/g;

/**
* Turns all package names into metacpan.org links within <a/> tags.
* @param {String} code Input code.
* @return {String} Returns code with </a> tags.
*/
function processPackages(code)
{
var destination = document.location.href.match(/\/source\//) ? 'source' : 'pod',
strip_delimiters = /((?:q[qw]?)?.)([A-Za-z0-9\:]+)(.*)/
;

code = code.replace(/(<code class="pl keyword">(?:with|extends|use<\/code> <code class="pl plain">(?:parent|base|aliased))\s*<\/code>\s*<code class="pl string">)(.+?)(<\/code>)/g, function(m,prefix,pkg,suffix)
{
var match = null,
mcpan_url
;

if ( match = strip_delimiters.exec(pkg) )
{
prefix = prefix + match[1];
pkg = match[2];
suffix = match[3] + suffix;
}

mcpan_url = '<a href="/' + destination + '/' + pkg + '">' + pkg + '</a>';
return prefix + mcpan_url + suffix;
});

// Link our dependencies
return code.replace(/(<code class="pl keyword">(use|package|require)<\/code> <code class="pl plain">)([A-Za-z0-9\:]+)(.*?<\/code>)/g, '$1<a href="/' + destination + '/$3">$3</a>$4');
};

var getCodeLinesHtml = SyntaxHighlighter.Highlighter.prototype.getCodeLinesHtml;
SyntaxHighlighter.Highlighter.prototype.getCodeLinesHtml = function(html, lineNumbers) {
html = html.replace(/^ /, "&#32;");
html = getCodeLinesHtml.call(this, html, lineNumbers);
return processPackages(html);
};

var getLineNumbersHtml = SyntaxHighlighter.Highlighter.prototype.getLineNumbersHtml;
SyntaxHighlighter.Highlighter.prototype.getLineNumbersHtml = function() {
var html = getLineNumbersHtml.apply(this, arguments);
html = html.replace(/(<div[^>]*>\s*)(\d+)(\s*<\/div>)/g, '$1<a href="#L$2" id="L$2">$2</a>$3');
return html;
};


var source = $("#source");
// if this is a source-code view with destination anchor
if (source.length && source.html().length > 500000) {
source.removeClass();
}
else if (source[0] && document.location.hash) {
// check for 'L{number}' anchor in URL and highlight and jump
// to that line.
var lineMatch = document.location.hash.match(/^#L(\d+)$/);
if (lineMatch) {
SyntaxHighlighter.defaults['highlight'] = [lineMatch[1]];
}
else {
// check for 'P{encoded_package_name}' anchor, convert to
// line number (if possible), and then highlight and jump
// as long as the matching line is not the first line in
// the code.
var packageMatch = document.location.hash.match(/^#P(\S+)$/);
if (packageMatch) {
var decodedPackageMatch = decodeURIComponent(packageMatch[1]);
var leadingSource = source.html().split("package " + decodedPackageMatch + ";");
var lineCount = leadingSource[0].split("\n").length;
if (leadingSource.length > 1 && lineCount > 1) {
SyntaxHighlighter.defaults['highlight'] = [lineCount];
document.location.hash = "#L" + lineCount;
}
else {
// reset the anchor portion of the URL (it just looks neater).
document.location.hash = '';
}
}
}
}

SyntaxHighlighter.highlight();

$('#signin-button').mouseenter(function () { $('#signin').show() });
$('#signin').mouseleave(function () { $('#signin').hide() });

Expand Down
Loading