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