Selaa lähdekoodia

Initial commit

master
achmizs 4 vuotta sitten
commit
eb2cfcf655
2 muutettua tiedostoa jossa 1939 lisäystä ja 0 poistoa
  1. 218
    0
      pastebin-embed.php
  2. 1721
    0
      simple_html_dom.php

+ 218
- 0
pastebin-embed.php Näytä tiedosto

@@ -0,0 +1,218 @@
<?php if (!defined('PmWiki')) exit();

$RecipeInfo['Pastebin Embed']['Version'] = '2017-12-27';

## (:pastebin-embed:)
Markup('pastebin-embed', '<fulltext', '/\\(:pastebin-embed\\s+(.+)\\s*:\\)/', 'PastebinEmbed');

SDV($PastebinEmbedHighlightStyle, "background-color: yellow;");

function PastebinEmbed ($m) {
static $id = 1;
## Parse arguments to the markup.
$parsed = ParseArgs($m[1]);

## These are the "bare" arguments (ones which don't require a key, just value(s)).
$args = $parsed[''];
$paste_id = $args[0];
$noJS = in_array('no-js', $args);
$noFooter = in_array('nofooter', $args);
$noLineNumbers = in_array('nolinenums', $args);
$raw = in_array('raw', $args);
$noPre = in_array('no-pre', $args);
## Convert the comma-delimited line ranges to an array containing each line to be
## included as values.
## Note that the line numbers will be zero-indexed (for use with raw text, etc.).
$line_ranges = $parsed['lines'] ? explode(',', $parsed['lines']) : array();
$line_numbers = array();
$to_end_from = -1;
foreach ($line_ranges as $key => $line_range) {
if (preg_match("/([0-9]+)[-–]([0-9]+)/", $line_range, $m)) {
$line_numbers = array_merge($line_numbers, range(--$m[1],--$m[2]));
} else if (preg_match("/([0-9]+)[-–]$/", $line_range, $m)) {
$line_numbers[] = $to_end_from = --$m[1];
} else {
$line_numbers[] = --$line_range;
}
}
## Same thing, but for highlighted line ranges.
$hl_line_ranges = $parsed['hl'] ? explode(',', $parsed['hl']) : array();
$hl_line_numbers = array();
$hl_to_end_from = -1;
foreach ($hl_line_ranges as $key => $hl_line_range) {
if (preg_match("/([0-9]+)[-–]([0-9]+)/", $hl_line_range, $m)) {
$hl_line_numbers = array_merge($hl_line_numbers, range(--$m[1],--$m[2]));
} else if (preg_match("/([0-9]+)[-–]$/", $hl_line_range, $m)) {
$hl_line_numbers[] = $hl_to_end_from = --$m[1];
} else {
$hl_line_numbers[] = --$hl_line_range;
}
}
$embed_js_url = "https://pastebin.com/embed_js/$paste_id";
$embed_iframe_url = "https://pastebin.com/embed_iframe/$paste_id";
$embed_raw_url = "https://pastebin.com/raw/$paste_id";
$out = "<span class='pastebin-embed-error'>Unknown error.</span>";
## There are three 'modes': raw (retrieve just the text, client-side, and insert it
## into the page), no-js (retrieve the HTML, server-side, and insert it into the
## page), and default (i.e., JS-based - insert the scriptlet, and let it retrieve and
## insert the HTML into the page, client-side & async).
## The mode is set by arguments to the (:pastebin-embed:) markup:
## - if neither the 'raw' nor the 'no-js' option is given, default (JS) mode is used
## - if the 'raw' option is given, raw mode is used
## - if the 'no-js' option is given, no-js mode is used
if ($raw) {
$raw_text = file_get_contents($embed_raw_url);
if (!$raw_text) return Keep("<span class='pastebin-embed-error'>Could not retrieve paste!</span>");
$raw_lines = explode("\n", $raw_text);
## Convert HTML entities.
if (!$noPre) {
foreach ($raw_lines as $line)
$line = PVSE($line);
}
## Highlighting only works if no-pre is NOT enabled.
if (!empty($hl_line_numbers) && !$noPre) {
if ($hl_to_end_from >= 0)
$hl_line_numbers = array_merge($hl_line_numbers, range($hl_to_end_from, count($raw_lines) - 1));
foreach ($hl_line_numbers as $l) {
$raw_lines[$l] = "<span class='pastebin-embed-highlighted-line'>" . rtrim($raw_lines[$l]) . "</span>";
}
}
## Filter by line number ranges, if specified.
if (!empty($line_numbers)) {
if ($to_end_from >= 0)
$line_numbers = array_merge($line_numbers, range($to_end_from, count($raw_lines) - 1));
$raw_lines = array_intersect_key($raw_lines, array_flip($line_numbers));
}
$raw_text = implode("\n", $raw_lines);
## The 'no-pre' option means we shouldn't wrap the text in a <pre> tag.
$out = $noPre ? $raw_text : Keep("<pre class='escaped embedPastebinRaw' id='pastebinEmbed_$id'>\n" . $raw_text . "\n</pre>\n");
} else if ($noJS) {
include_once('simple_html_dom.php');
$content_html = file_get_html($embed_iframe_url);
if (!$content_html) return Keep("<span class='pastebin-embed-error'>Could not retrieve paste!</span>");
$content = $content_html->find(".embedPastebin", 0);
$content->id = "pastebinEmbed_$id";
$styles_html = file_get_html($embed_js_url);
if (!$styles_html) return Keep("<span class='pastebin-embed-error'>Could not retrieve styles!</span>");
$styles = $styles_html->find("style", 0);
## Filter specified line ranges (if any have been specified via the lines=
## parameter).
if (!empty($line_numbers)) {
$lines = $content_html->find(".embedPastebin > ol > li");
if ($to_end_from >= 0)
$line_numbers = array_merge($line_numbers, range($to_end_from, count($lines) - 1));
foreach ($lines as $i => $line) {
if (!in_array($i, $line_numbers))
$line->outertext = '';
else
$line->value = ++$i;
}
}
## Highlight specified line ranges (if any have been specified via the hl=
## parameter).
if (!empty($hl_line_numbers)) {
$lines = $content_html->find(".embedPastebin > ol > li");
if ($hl_to_end_from >= 0)
$hl_line_numbers = array_merge($hl_line_numbers, range($hl_to_end_from, count($lines) - 1));
foreach ($lines as $i => $line) {
if (in_array($i, $hl_line_numbers)) {
$line->children(0)->class .= " pastebin-embed-highlighted-line";
}
}
}
$out = Keep($styles.$content);
} else {
$out = Keep("<script id='pastebinEmbedScript_$id' src='$embed_js_url'></script>");

if (!empty($hl_line_numbers) || !empty($line_numbers)) {
$line_numbers_js = "[ ".implode(", ",$line_numbers)." ]";
$hl_line_numbers_js = "[ ".implode(", ",$hl_line_numbers)." ]";
$out .= Keep("
<script>
var num_lines = document.querySelector('#pastebinEmbedScript_$id').parentElement.nextSibling.querySelectorAll('.embedPastebin > ol > li').length;
var line_numbers = $line_numbers_js;
var to_end_from = $to_end_from;
if (to_end_from >= 0)
line_numbers = [...line_numbers, ...[...Array(num_lines - to_end_from)].map((_, i) => to_end_from + i)];

var hl_line_numbers = $hl_line_numbers_js;
var hl_to_end_from = $hl_to_end_from;
if (hl_to_end_from >= 0)
hl_line_numbers = [...hl_line_numbers, ...[...Array(num_lines - hl_to_end_from)].map((_, i) => hl_to_end_from + i)];

document.querySelector('#pastebinEmbedScript_$id').parentElement.nextSibling.querySelectorAll('.embedPastebin > ol > li').forEach(function (line, i) {
// Highlight specified line ranges (if any have been specified via the hl= parameter).
if (hl_line_numbers.indexOf(i) != -1)
line.firstChild.className += ' pastebin-embed-highlighted-line';

// Filter specified line ranges (if any have been specified via the lines= parameter).
if (line_numbers.length > 0) {
if (line_numbers.indexOf(i) == -1)
line.parentElement.removeChild(line);
else
line.value = ++i;
}
});
</script>
");
}
PastebinEmbedAppendFooter();
}
global $HTMLStylesFmt;
if (!$raw && $noFooter) {
$HTMLStylesFmt['pastebin-embed'][] = "#pastebinEmbed_$id .embedFooter { display: none; }\n";
}
if (!$raw && $noLineNumbers) {
$HTMLStylesFmt['pastebin-embed'][] = "#pastebinEmbed_$id > ol { padding-left: 5px; }\n";
}
PastebinEmbedInjectStyles();
$id++;
return $out;
}

function PastebinEmbedAppendFooter() {
static $ran_once = false;
if (!$ran_once) {
global $HTMLFooterFmt;
$HTMLFooterFmt[] =
"<script>
document.querySelectorAll('div.embedPastebin').forEach(function (embed) {
if (embed.previousSibling && embed.previousSibling.tagName == 'P') {
embed.id = 'pastebinEmbed_' + embed.previousSibling.firstChild.id.substring(20);
}
});
</script>\n";
}
$ran_once = true;
}

function PastebinEmbedInjectStyles() {
static $ran_once = false;
if (!$ran_once) {
global $HTMLStylesFmt, $PastebinEmbedHighlightStyle;
$styles = "
.embedPastebinRaw .pastebin-embed-highlighted-line { $PastebinEmbedHighlightStyle display: inline-block; width: calc(100% + 4px); padding-left: 4px; margin-left: -4px; }
.embedPastebin li .pastebin-embed-highlighted-line { $PastebinEmbedHighlightStyle }
";
$HTMLStylesFmt['pastebin-embed'][] = $styles;
}
$ran_once = true;
}

+ 1721
- 0
simple_html_dom.php
File diff suppressed because it is too large
Näytä tiedosto


Loading…
Peruuta
Tallenna