initial
This commit is contained in:
45
README.md
Normal file
45
README.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# MDSnippets #
|
||||
|
||||
MDSnippets is a static HTML page with JS markdown parser to create a
|
||||
generic snippet storage
|
||||
|
||||
Snippets are syntax highlighted with [highlight.js](https://highlightjs.org).
|
||||
See their documentation for language names.
|
||||
|
||||
## UI
|
||||
|
||||
* At the top there is a search bar. Enter values to filter snippet names.
|
||||
* Pressing key 's' or / focuses the search bar.
|
||||
|
||||
## Configuration
|
||||
|
||||
* config.js
|
||||
* File is read to replace values in "config.xx" object.
|
||||
* config.source='path_to_markdown.txt';
|
||||
* config.style='path_to_style.css';
|
||||
* config.title='Title of page';
|
||||
* config.search=true; // Display link search bar
|
||||
* config.favicon='path_to_favicon.ico';
|
||||
|
||||
## Markdown
|
||||
|
||||
Only 1st level heads, names and code blocks are parsed:
|
||||
```
|
||||
# header
|
||||
|
||||
name
|
||||
\`\`\`python
|
||||
print("Hello World!")
|
||||
# Dot escape the ticks in real config.
|
||||
\`\`\`
|
||||
|
||||
```
|
||||
|
||||
## Static HTML builder
|
||||
|
||||
Sometimes the reloading of styles and links is hard due to caching.
|
||||
You can create a static single HTML page with:
|
||||
|
||||
```
|
||||
bash build_static.sh -l example_snippets.txt -c config.js -s style.css > templated.html
|
||||
```
|
||||
107
build_static.sh
Executable file
107
build_static.sh
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
|
||||
_help() {
|
||||
echo "Pass arguments to create a static version of the index, printed on stdout
|
||||
Templating will replace config values config.style and config.source to null
|
||||
|
||||
-l [snippets.txt] Path to snippets.txt. must be passed
|
||||
-c [config.js] *Path to configuration js replacing config values
|
||||
-s [styles.css] *Path to extra styles
|
||||
|
||||
* can be left out
|
||||
"
|
||||
exit
|
||||
}
|
||||
|
||||
_checkenv() {
|
||||
if [[ ! -e "$SNIPPETS" ]]; then
|
||||
echo "Snippets file '$SNIPPETS' not found."
|
||||
_help
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$CONFIG" ]]; then
|
||||
if [[ ! -e "$CONFIG" ]]; then
|
||||
echo "Config file '$CONFIG' not found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$STYLE" ]]; then
|
||||
if [[ ! -e "$STYLE" ]]; then
|
||||
echo "Styles file '$STYLE' not found."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "
|
||||
Snippets file: $SNIPPETS
|
||||
Config file: $CONFIG
|
||||
Style file: $STYLE
|
||||
" >&2
|
||||
|
||||
}
|
||||
_replace_snippets() {
|
||||
if [[ -e "$SNIPPETS" ]]; then
|
||||
sniptmp=$( mktemp )
|
||||
sed 's/`/\\`/g' "$SNIPPETS" > "$sniptmp"
|
||||
sed \
|
||||
-e '/TEMPLATED:SNIPPETS/a config.source=null;' \
|
||||
-e '/TEMPLATED:SNIPPETS/a config.snippets=`' \
|
||||
-e "/TEMPLATED:SNIPPETS/r $sniptmp" \
|
||||
-e '/TEMPLATED:SNIPPETS/a `;'
|
||||
#-e "/TEMPLATED:SNIPPETS/d"
|
||||
rm -f "$sniptmp"
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
_replace_config() {
|
||||
if [[ -e "$CONFIG" ]]; then
|
||||
sed \
|
||||
-e "/TEMPLATED:CONFIG/r $CONFIG" \
|
||||
-e "/^.script language.*config.js.*script.*/d"
|
||||
#-e "/TEMPLATED:CONFIG/d"
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
_replace_style() {
|
||||
if [[ -e "$STYLE" ]]; then
|
||||
sed \
|
||||
-e "/TEMPLATED:STYLE/r $STYLE" \
|
||||
-e '/TEMPLATED:CONFIG/a config.style=null;' \
|
||||
#-e "/TEMPLATED:STYLE/d"
|
||||
else
|
||||
cat -
|
||||
fi
|
||||
}
|
||||
_inject_dependencies() {
|
||||
|
||||
sed \
|
||||
-e "/TEMPLATED:HIGHLIGHT_STYLE/r $SELFDIR/default.min.css" \
|
||||
-e "/TEMPLATED:HIGHLIGHT_STYLE/r $SELFDIR/dark.min.css" \
|
||||
-e "/TEMPLATED:HIGHLIGHT_CODE/r $SELFDIR/highlight.min.js" \
|
||||
-e "/stylesheet.*default.min.css/d" \
|
||||
-e "/stylesheet.*dark.min.css/d" \
|
||||
-e "/script.*highlight.min.js/d"
|
||||
|
||||
}
|
||||
_replace() {
|
||||
cat "$SELFDIR"/index.html | _replace_snippets | _replace_style | _replace_config | _inject_dependencies
|
||||
}
|
||||
|
||||
SELFDIR=$( dirname $( readlink -f "$0") )
|
||||
CONFIG=
|
||||
STYLE=
|
||||
SNIPPETS=
|
||||
|
||||
for (( i=1; i<=$#; i++ )); do
|
||||
j=$(( i + 1 ))
|
||||
[[ "${!i}" = "-h" ]] && _help
|
||||
[[ "${!i}" = "--help" ]] && _help
|
||||
[[ "${!i}" = "-l" ]] && { SNIPPETS="${!j}"; shift 1; continue; }
|
||||
[[ "${!i}" = "-c" ]] && { CONFIG="${!j}"; shift 1; continue; }
|
||||
[[ "${!i}" = "-s" ]] && { STYLE="${!j}"; shift 1; continue; }
|
||||
done
|
||||
|
||||
_checkenv
|
||||
_replace
|
||||
1
dark.min.css
vendored
Normal file
1
dark.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#ddd;background:#303030}.hljs-keyword,.hljs-link,.hljs-literal,.hljs-section,.hljs-selector-tag{color:#fff}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-name,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#d88}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#979797}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic}
|
||||
9
default.min.css
vendored
Normal file
9
default.min.css
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
Theme: Default
|
||||
Description: Original highlight.js style
|
||||
Author: (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
|
||||
Maintainer: @highlightjs/core-team
|
||||
Website: https://highlightjs.org/
|
||||
License: see project LICENSE
|
||||
Touched: 2021
|
||||
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
||||
5
example_config.js
Normal file
5
example_config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
config.title = "MDSnippets";
|
||||
config.search = true;
|
||||
config.source = "example_snippets.txt";
|
||||
config.favicon = null; // link to favicon
|
||||
config.style = null; // link to style file
|
||||
49
example_snippets.txt
Normal file
49
example_snippets.txt
Normal file
@@ -0,0 +1,49 @@
|
||||
# Help
|
||||
|
||||
Usage
|
||||
```plaintext
|
||||
Search at top^
|
||||
|
||||
Use Tab or click item to show code.
|
||||
Code is selected automatically, just ctrl-c or copy.
|
||||
Code is stored in a markdown file: example_snippets.txt
|
||||
|
||||
snippets syntax:
|
||||
======
|
||||
# header
|
||||
|
||||
item1
|
||||
` ``Language
|
||||
Language code
|
||||
` ``
|
||||
^ note no space in between in real life
|
||||
|
||||
item2
|
||||
` ``bash
|
||||
for e in *; do loop $e;done
|
||||
` ``
|
||||
======
|
||||
|
||||
```
|
||||
|
||||
# Python
|
||||
|
||||
Hello
|
||||
```python
|
||||
print("HELLO")
|
||||
```
|
||||
|
||||
sql
|
||||
```SQL
|
||||
SELECT
|
||||
*
|
||||
FROM {WORK.TABLE.r()}
|
||||
```
|
||||
|
||||
# Bash
|
||||
|
||||
for files
|
||||
```bash
|
||||
for e in *; do echo "$e"; done
|
||||
```
|
||||
|
||||
1207
highlight.min.js
vendored
Normal file
1207
highlight.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
708
index.html
Normal file
708
index.html
Normal file
@@ -0,0 +1,708 @@
|
||||
<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, " ");
|
||||
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">↻</a></span>
|
||||
</body>
|
||||
</html>
|
||||
3
instant_webserver.sh
Normal file
3
instant_webserver.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
exec python3 -m http.server 8123
|
||||
Reference in New Issue
Block a user