Files
mdsnippets/index.html
2023-09-27 19:51:55 +03:00

709 lines
16 KiB
HTML

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="default.min.css">
<link rel="stylesheet" href="dark.min.css">
<script src="highlight.min.js"></script>
<STYLE type="text/css">
HTML {
--txt-col: #ddd;
--high-col: rgb(255, 255, 255);
--head-col: #AFC2FF;
--fg-col: #eee;
--bg-col: #282828;
--filt-col: #AFC2FF;
}
BODY {
color: var(--txt-col);
background-color: var(--bg-col);
}
#main {
display: flex;
width: 100%;
min-height: 100%;
}
.tableWrapper {
flex: 1;
min-width: 20%;
max-width: 50%;
}
.snippetWrapper {
flex: 2;
min-width: 50%;
max-width: 80%;
}
.code {
margin-left: 0.4em;
margin-right: 0.4em;
border: 1px solid black;
height: calc(100vh - 5em);
max-height: calc(100vh - 5em);
}
#hiddenCode {
display: inline-block;
max-width: 15em;
height: 1.2em;
overflow: hidden;
}
#snippet {
display: block;
padding: 0.4em;
white-space: pre-wrap;
overflow-x: hidden;
overflow-y: auto;
height: calc(100vh - 8em);
max-height: calc(100vh - 8em);
}
TABLE {}
HR {
height: 5px;
border: 0px;
}
TD {
vertical-align: top;
width: 10%;
}
LI {
text-indent: -1.3em;
padding-left: 1.4em;
list-style-type: none;
overflow: hidden;
margin-bottom: 0.2em;
}
LI:before {
content: "-";
padding-right: 0.5em;
}
TD.narrow LI {
margin-bottom: 1em;
}
LI.nolink:before {
content: " ";
padding-right: 1.0em;
}
A.link {
text-decoration: none;
color: var(--txt-col);
cursor: pointer;
}
A.link:hover {
text-decoration: underline;
var(--txt-col);
}
A.link:focus {
text-decoration: underline;
}
A.selectedName {
color: var(--high-col);
}
#filter {
width: 100%;
background-color: var(--filt-col);
color: var(--bg-col);
}
#search {
width: 100%;
display: table;
}
.search_span {
display: table-cell;
text-align: center;
vertical-align: middle;
padding-left: 0.1em;
padding-right: 0.1em;
}
.head {
text-align: left;
padding-top: 0.2em;
margin-bottom: -0.5em;
color: var(--head-col);
}
#menu {
width: 3em;
background: var(--bg-col);
border-color: var(--fg-col);
border-width: 2px;
color: var(--txt-col);
}
.tickbox {}
#reload_span {
float: right;
}
hr {
background-color: var(--head-col);
/*box-shadow: 0px 3px var(--high-col), 0px -3px var(--txt-col);
border-radius: 0px;*/
}
.hidden {
display: none;
}
.fold_plus::after {
content: " (+)";
vertical-align: super;
font-size: 50%;
}
.blink {
-webkit-animation: blinker 0.5s infinite;
-moz-animation: blinker 0.5s infinite;
animation: blinker 0.5s infinite;
}
@keyframes blinker {
0% {
opacity: 0.00;
}
100% {
opacity: 1.00;
}
}
/* TEMPLATED:STYLE */
/* TEMPLATED:HIGHLIGHT_STYLE */
</STYLE>
<script language="javascript">
function init() {
var head = document.head;
if (config.style != null) {
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = config.style;
head.appendChild(link);
}
if (config.favicon != null) {
var link = document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'icon';
link.href = config.favicon;
head.appendChild(link);
}
var title = document.createElement('title');
title.innerHTML = config.title;
head.appendChild(title);
if (!config.search) {
document.getElementById('search').style.display = 'none';
}
document.getElementById("filter").focus();
filter_load();
hitList = search_hits(document.getElementById("filter").value);
print_results(hitList);
fold_initial();
scroll_load();
parse_request();
}
String.prototype.capitalizeFirstLetter = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
function show_code(element, c) {
var positionY = window.scrollY;
var links = document.getElementsByTagName('a');
for (i = 0; i < links.length; i++) {
links[i].classList.remove("selectedName");
}
element.classList.add("selectedName");
var snippet = document.getElementById('snippet');
snippet.className = snippet.className.split(" ").filter(function(c) {
return c.lastIndexOf("language-", 0) !== 0;
}).join(" ");
snippet.classList.add(`language-${snippetList[c].language}`);
snippet.innerHTML = snippetList[c].value;
hljs.highlightElement(snippet);
window.scrollTo(0, positionY);
var hidden = document.getElementById('hiddenCode');
hidden.innerHTML = snippetList[c].value;
select_text(hidden);
}
function make_link(c) {
var l = document.createElement('a');
l.innerHTML = snippetList[c].name;
l.classList.add("link");
l.href = "#";
l.id = `link_${c}`;
l.onclick = function(event) {
show_code(this, c);
event.preventDefault();
}
l.onfocus = function() {
show_code(this, c);
}
var li = document.createElement('li');
li.appendChild(l);
return li
}
function open_snippet(hit) {
document.getElementById(`link_${hit}`).click();
}
function select_text(id) {
window.getSelection()
.selectAllChildren(
id
);
}
function make_head(c, index = "") {
var name = c.name.substring(1).trim();
var head = c.name.replace(/ /g, "&nbsp;");
var id = name.replace(/ /g, "") + "_" + index;
return '<a name="' + name + '" id="anchor_' + id + '" class="nolink" onclick="fold_toggle(\'' + id + '\')">' +
'<div class=head align=center id="head_' + id + '">' + head + '</div></a>' +
'<hr WIDTH="100%" SIZE=3 NOSHADE>';
}
function filter(ev) {
var needle = document.getElementById('filter').value;
set_cookie("filter", needle);
hitList = search_hits(needle);
var c = hitList.length;
var lastHit = hitList[c - 1];
print_results(hitList);
// At parsing:
if (ev == null) {
if (c == 1) {
open_snippet(lastHit);
};
return
}
// At manual entry:
var key = ev.keyCode;
if (key == 13) {
if (c == 0) {
document.getElementById('filter').focus();
}
if (c == 1) {
open_snippet(lastHit);
}
if (c > 1) {
document.getElementById('filter').focus();
}
}
}
function no_filter() {}
function search_hits(needle) {
needle = needle.trim().toLowerCase();
if (needle == "") {
return Array.apply(null, {
length: snippetList.length
}).map(Number.call, Number);
}
hitList = [];
var headName = "";
for (l = 0; l < snippetList.length; l++) {
if (snippetList[l].type == "head") {
headName = snippetList[l].name.replace(/ /g, "").toLowerCase();
}
if (needle.substring(0, 1) == "#") {
/* search for header */
if (headName.indexOf(needle.substring(1).trim()) > -1) {
/* current header matches */
hitList.push(l);
continue
}
}
if (snippetList[l].name.toLowerCase().indexOf(needle) > -1) {
hitList.push(l);
continue
}
}
return hitList
}
var cats = [];
function print_results(hitList) {
var str = "";
var cat = 0;
cats = [];
var td = document.createElement("td"); // If there are no heads to startwith
var td_content = document.createElement("div");
td.appendChild(td_content);
cats.push({
name: 'N/A',
td: td,
count: 0
});
cat += 1;
for (c = 0; c < snippetList.length; c++) {
if (snippetList[c].type == "head") {
var name = snippetList[c].name.substring(1).trim().replace(/ /g, "");
var td = document.createElement("td");
td.id = "td_" + name + "_" + cat;
var td_content = document.createElement("div");
td_content.id = "content_" + name + "_" + cat;
td.innerHTML += make_head(snippetList[c], cat);
td.appendChild(td_content);
cats.push({
name: name,
td: td,
count: 0
});
cat += 1;
} else {
if (hitList.indexOf(c) == -1) {
continue
}
td_content.appendChild(make_link(c));
cats[cat - 1].count++;
}
}
var doc = document.getElementById("main");
doc.innerHTML = "";
var snippetWrapper = document.createElement("div");
snippetWrapper.classList.add('snippetWrapper');
var tableWrapper = document.createElement("div");
tableWrapper.classList.add('tableWrapper');
var tbl = document.createElement("table");
var tbody = document.createElement("tbody");
var tr = document.createElement("tr");
var print_cat = 0;
for (cat = 0; cat < cats.length; cat++) {
if (cats[cat].count > 0) {
var tr = document.createElement("tr");
tbody.appendChild(tr);
tr.appendChild(cats[cat].td);
print_cat++;
}
}
var pre = document.createElement("pre")
var hidden = document.createElement("span")
var snippet = document.createElement("code")
var copy_doc = document.createElement("span")
snippet.id = "snippet";
hidden.id = "hiddenCode";
pre.id = "pre";
pre.classList.add("code");
copy_doc.id = "copyDoc";
copy_doc.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" role="presentation"><g fill="currentColor"><path d="M10 19h8V8h-8v11zM8 7.992C8 6.892 8.902 6 10.009 6h7.982C19.101 6 20 6.893 20 7.992v11.016c0 1.1-.902 1.992-2.009 1.992H10.01A2.001 2.001 0 018 19.008V7.992z"></path><path d="M5 16V4.992C5 3.892 5.902 3 7.009 3H15v13H5zm2 0h8V5H7v11z"></path></g></svg>';
snippet.onfocus = function() {
select_text(this);
}
snippet.onclick = function() {
select_text(this);
}
hidden.onfocus = function() {
select_text(this);
}
hidden.onclick = function() {
select_text(this);
}
pre.appendChild(snippet);
pre.appendChild(copy_doc);
pre.appendChild(hidden);
snippetWrapper.appendChild(pre);
tbody.appendChild(tr);
tbl.appendChild(tbody);
tableWrapper.appendChild(tbl);
doc.appendChild(tableWrapper);
doc.appendChild(snippetWrapper);
}
function reload_source() {
location.href = config.source
}
function get_URL(s) {
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
parse_snippets(xmlhttp.responseText);
}
}
xmlhttp.open("GET", s, true);
xmlhttp.send();
}
function read_snippets() {
if (config.source === null && config.snippets) {
parse_snippets(config.snippets);
} else {
get_URL(config.source);
}
}
function parse_snippets(s) {
var rows = s.split("\n");
var snippets = [];
var codeOpen = false;
var code = '';
var title = '';
var lang = '';
for (r = 0; r < rows.length; r++) {
if (!codeOpen) {
if (rows[r].substring(0, 3) == '```') {
codeOpen = true;
code = "";
lang = rows[r].substring(3);
lang = (lang.length > 0) ? lang : 'plaintext';
} else {
if (rows[r].length > 1) {
if (rows[r].substring(0, 2) == "# ") {
snippets.push({
'name': rows[r],
'type': 'head',
})
} else {
title = rows[r];
}
}
}
} else {
if (rows[r] == '```') {
codeOpen = false;
snippets.push({
'name': title,
'type': 'code',
'value': code,
'language': lang
});
title = 'Unnamed';
} else {
code += rows[r] + "\n"
}
}
}
snippetList = snippets.slice(0);
init();
}
function parse_request() {
var request = window.location.search.substring(1);
var vars = request.split('&');
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=');
if (decodeURIComponent(pair[0]) == "filter") {
var value = decodeURIComponent(pair[1]);
document.getElementById("filter").value = value;
filter(null);
}
}
}
function keyboard_entry(ev) {
var kC = ev.keyCode;
var k = String.fromCharCode(ev.keyCode);
var ctrlDown = ev.ctrlKey || ev.metaKey;
if (document.activeElement === document.getElementById("filter")) {
return
}
if (/S/.test(k) || kC == 191) { // slash or S
document.getElementById("filter").focus();
}
}
function scroll_page() {
if (document.getElementById('pre')) {
document.getElementById('pre').style.marginTop = `${window.scrollY}px`;
}
scroll_save()
}
function scroll_save() {
set_cookie("position", window.scrollY);
}
function scroll_load() {
var position = parseInt(get_cookie("position"));
window.scrollTo(0, position);
}
function filter_load() {
var needle = get_cookie("filter");
if (needle === null) {
return;
}
if (needle.startsWith("/")) {
needle = "";
}
document.getElementById("filter").value = needle;
}
function get_cookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(";");
var cookies = Array();
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) {
cookies.push(c.substring(nameEQ.length, c.length));
}
}
return filter_cookies(cookies, name)
}
function filter_cookies(cookies, name) {
// return only cookies that have the pathname
for (var i = 0; i < cookies.length; i++) {
var c = cookies[i];
var split = c.split("&");
if (split.length == 2) {
if (split[1] == window.location.pathname) {
return split[0];
}
}
}
return null;
}
function fold_toggle(name, save_state = true) {
if (!config.foldCategories) {
return
}
var title = document.getElementById("head_" + name);
var el = document.getElementById("content_" + name);
el.hidden = !el.hidden;
title.classList.toggle("fold_plus");
if (save_state) {
set_cookie("fold", fold_get_state());
}
}
function fold_set(name, value) {
if (!config.foldCategories) {
return
}
var title = document.getElementById("head_" + name);
var el = document.getElementById("content_" + name);
el.hidden = value;
if (value) {
title.classList.add("fold_plus");
} else {
title.classList.remove("fold_plus");
}
}
function fold_initial() {
if (!config.foldCategories) {
return
}
var state = get_cookie("fold");
if (state !== null) {
fold_set_state(state);
return;
}
var slides = document.getElementsByClassName("head");
for (var i = 0; i < slides.length; i++) {
var el = slides.item(i);
var rect = el.getBoundingClientRect();
if (window.innerHeight * 1.5 < rect.top) {
var name = el.id.replace("head_", "");
fold_toggle(name);
}
}
}
function fold_get_state() {
var slides = document.getElementsByClassName("head");
var state = "";
for (var i = 0; i < slides.length; i++) {
var title = slides.item(i);
var name = title.id.replace("head_", "");
var el = document.getElementById("content_" + name);
if (el.hidden) {
state += '-';
} else {
state += '+';
}
}
return state;
}
function fold_set_state(state) {
var slides = document.getElementsByClassName("head");
for (var i = 0; i < slides.length; i++) {
var title = slides.item(i);
var name = title.id.replace("head_", "");
if (state[i] == '-') {
fold_set(name, true);
}
if (state[i] == '+') {
fold_set(name, false);
}
}
return;
}
function set_cookie(name, value) {
// Save cookies for 30 minutes
document.cookie = name + "=" + value.toString() + "&" + window.location.pathname +
";path=" + window.location.pathname + ";max-age=" + (60 * 30).toString() + ";";
}
function clear() {
document.getElementById("filter").value = '';
filter(true);
}
document.onkeyup = keyboard_entry;
document.onscroll = scroll_page;
var snippetList = [];
var hitList = [];
var config = {
title: 'MDSnippets', // title of snippets
source: 'snippets.txt', // file for snippets
search: true, // include search bar
style: null, // file to load css from
favicon: null, // link to favicon file
};
// TEMPLATED:HIGHLIGHT_CODE
// TEMPLATED:CONFIG
// TEMPLATED:SNIPPETS
</script>
<script language="javascript" src="config.js"></script>
</head>
<body onload="read_snippets()">
<div id="search">
<span class="search_span"><input type="text" oninput="filter(event)" onkeypress="filter(event)" onblur="no_filter()" id="filter" title="[s] Filter snippets by name"></span>
</div>
<div id="main"></div>
<span class="search_span" id="reload_span"><a href="#" onclick="reload_source()" title="Reload snippets source">&#8635;</a></span>
</body>
</html>