clickable footnotes
This commit is contained in:
parent
b133915626
commit
803cd89fe4
@ -71,10 +71,10 @@ function sphinx_client(): Sphinx\SphinxClient {
|
|||||||
|
|
||||||
function _sphinx_normalize(string $origstr): string {
|
function _sphinx_normalize(string $origstr): string {
|
||||||
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
|
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
|
||||||
if (!pcre_check_error($buf, no_error: true)) {
|
if (!pcre_no_error($buf, no_error: true)) {
|
||||||
$origstr = mb_convert_encoding($origstr, 'UTF-8', 'UTF-8');
|
$origstr = mb_convert_encoding($origstr, 'UTF-8', 'UTF-8');
|
||||||
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
|
$buf = preg_replace('/[Ёё]/iu', 'е', $origstr);
|
||||||
pcre_check_error($buf);
|
pcre_no_error($buf);
|
||||||
}
|
}
|
||||||
if ($buf === null) {
|
if ($buf === null) {
|
||||||
logError(__METHOD__.': preg_replace() failed with error: '.preg_last_error().': '.preg_last_error_msg());
|
logError(__METHOD__.': preg_replace() failed with error: '.preg_last_error().': '.preg_last_error_msg());
|
||||||
|
@ -297,7 +297,7 @@ function is_retina(): bool { return isset($_COOKIE['is_retina']) && $_COOKIE['is
|
|||||||
function jsonEncode($obj): ?string { return json_encode($obj, JSON_UNESCAPED_UNICODE) ?: null; }
|
function jsonEncode($obj): ?string { return json_encode($obj, JSON_UNESCAPED_UNICODE) ?: null; }
|
||||||
function jsonDecode($json) { return json_decode($json, true); }
|
function jsonDecode($json) { return json_decode($json, true); }
|
||||||
|
|
||||||
function pcre_check_error(mixed &$result, bool $no_error = false): bool {
|
function pcre_no_error(mixed &$result, bool $no_error = false): bool {
|
||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
if (preg_last_error() !== PREG_NO_ERROR) {
|
if (preg_last_error() !== PREG_NO_ERROR) {
|
||||||
if (!$no_error)
|
if (!$no_error)
|
||||||
|
@ -506,3 +506,32 @@ body.wide .blog-post {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.blog-footnote-ref, a.blog-ref {
|
||||||
|
display: inline-block;
|
||||||
|
color: $blog-ref-color;
|
||||||
|
font-family: "Liberation Mono", monospace;
|
||||||
|
font-size: $fs - 2px;
|
||||||
|
letter-spacing: -0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.blog-ref {
|
||||||
|
@include no-underline();
|
||||||
|
padding: 0 1px;
|
||||||
|
margin-left: -2px;
|
||||||
|
}
|
||||||
|
@media (hover: hover) {
|
||||||
|
a.blog-ref:hover {
|
||||||
|
color: $blog-ref-color-hover;
|
||||||
|
background-color: $blog-ref-bg-hover;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.blog-footnote-line:target {
|
||||||
|
background-color: $blog-ref-bg-hover;
|
||||||
|
border-radius: 3px;
|
||||||
|
a {
|
||||||
|
@include no-underline(true);
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,9 @@
|
|||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
html, body {
|
html, body {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -50,6 +50,10 @@ $pn-button-current-text-color: $bg;
|
|||||||
|
|
||||||
$head-items-separator: #5e6264;
|
$head-items-separator: #5e6264;
|
||||||
|
|
||||||
|
$blog-ref-color: $dark-grey;
|
||||||
|
$blog-ref-color-hover: #8c9aab;
|
||||||
|
$blog-ref-bg-hover: $hover-hl;
|
||||||
|
|
||||||
// colors from https://github.com/Kelbster/highlightjs-material-dark-theme/blob/master/css/materialdark.css
|
// colors from https://github.com/Kelbster/highlightjs-material-dark-theme/blob/master/css/materialdark.css
|
||||||
$hljs_fg: #CDD3D8;
|
$hljs_fg: #CDD3D8;
|
||||||
$hljs_bg: #2B2B2D;
|
$hljs_bg: #2B2B2D;
|
||||||
|
@ -52,6 +52,10 @@ $pn-button-current-text-color: $fg;
|
|||||||
|
|
||||||
$head-items-separator: #d0d0d0;
|
$head-items-separator: #d0d0d0;
|
||||||
|
|
||||||
|
$blog-ref-color: #888;
|
||||||
|
$blog-ref-color-hover: #6a88ab;
|
||||||
|
$blog-ref-bg-hover: #f0f5fa;
|
||||||
|
|
||||||
// github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
// github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||||
$hljs_fg: #333;
|
$hljs_fg: #333;
|
||||||
$hljs_bg: #f8f8f8;
|
$hljs_bg: #f8f8f8;
|
||||||
|
@ -11,9 +11,35 @@ class markup {
|
|||||||
bool $no_paragraph = false): string {
|
bool $no_paragraph = false): string {
|
||||||
$pd = new MyParsedown(useImagePreviews: $use_image_previews, lang: $lang);
|
$pd = new MyParsedown(useImagePreviews: $use_image_previews, lang: $lang);
|
||||||
$html = $pd->text($md);
|
$html = $pd->text($md);
|
||||||
if ($no_paragraph) {
|
|
||||||
|
if ($no_paragraph)
|
||||||
$html = preg_replace('/<p>(.*?)<\/p>/', '$1', $html);
|
$html = preg_replace('/<p>(.*?)<\/p>/', '$1', $html);
|
||||||
|
|
||||||
|
else {
|
||||||
|
// collect references
|
||||||
|
$re = '/^<p>(\[([io]?\d{1,2})]) (.*?)<\/p>/m';
|
||||||
|
$result = preg_match_all($re, $html, $matches);
|
||||||
|
if (pcre_no_error($result)) {
|
||||||
|
$reftitles_map = [];
|
||||||
|
foreach ($matches[2] as $i => $refname) {
|
||||||
|
$reftitles_map[$refname] = trim(strip_tags($matches[3][$i]));
|
||||||
}
|
}
|
||||||
|
$span_opening_tag = '<span class="blog-footnote-ref">';
|
||||||
|
$html = preg_replace($re, '<p class="blog-footnote-line" id="footnote_$2">'.$span_opening_tag.'$1</span> $3</p>', $html);
|
||||||
|
$re = '/'.implode('|', array_map(fn($m) => '(?:'.$span_opening_tag.')?'.preg_quote($m, '/'), $matches[1])).'/';
|
||||||
|
$html = preg_replace_callback($re,
|
||||||
|
function($match) use ($span_opening_tag, $reftitles_map) {
|
||||||
|
if (str_starts_with($match[0], $span_opening_tag))
|
||||||
|
return $match[0];
|
||||||
|
if (!preg_match('/\[([io]?\d{1,2})]/', $match[0], $refmatch))
|
||||||
|
return $match[0];
|
||||||
|
$refname = $refmatch[1];
|
||||||
|
$reftitle = $reftitles_map[$refname];
|
||||||
|
return '<a href="#footnote_'.$refname.'" class="blog-ref" title="'.htmlescape($reftitle).'">'.$match[0].'</a>';
|
||||||
|
}, $html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user