add klipse and blog post about it

This commit is contained in:
Tom 2023-07-20 16:48:57 +01:00
parent fde76198db
commit 9bd39eaf7e
9 changed files with 2702 additions and 50 deletions

View File

@ -12,4 +12,4 @@ You probably want to run ruby from a version manager like `chruby`, see [here](h
[Installation](https://jekyllrb.com/docs/installation/macos/) [Installation](https://jekyllrb.com/docs/installation/macos/)
`bundle install` `bundle install`
Then Then
Use `bundle exec jekyll serve --draft --future` to do local development of this site Use `./run.sh` to do local development of this site

View File

@ -0,0 +1,46 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- HTML Meta Tags -->
<title>Tom Hodson - {{ page.title }}</title>
<meta property="og:title" content="Tom Hodson - {{ page.title }}">
<meta name="twitter:title" content="Tom Hodson - {{ page.title }}">
<meta name="description" content="{{page.excerpt | strip_html | strip}}">
<meta property="og:description" content="{{page.excerpt | strip_html | strip}}">
<meta name="twitter:description" content="{{page.excerpt | strip_html | strip}}">
<meta property="og:url" content="{{site.url}}{{page.url}}">
<meta property="twitter:domain" content="thomashodson.com">
<meta property="twitter:url" content="{{site.url}}{{page.url}}">
<meta property="og:type" content="website">
{% if page.image %}
<meta name="twitter:card" content="{{site.url}}{{page.image}}">
<meta name="twitter:image" content="{{site.url}}{{page.image}}">
<meta property="og:image" content="{{site.url}}{{page.image}}">
{% if page.alt %} <!-- Note og:image:alt must immediately follow og:image tag -->
<meta property="og:image:alt" content="{{page.alt | strip}}">
{% endif %}
{% endif %}
<link rel="stylesheet" href="/assets/css/styles.css">
<script src="/assets/js/index.js"></script>
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
svg: {
fontCache: 'global'
}
};
</script>
<script src="/assets/mathjax/tex-mml-svg.js" id="MathJax-script" async></script>
<!-- RSS feed -->
{% feed_meta %}

View File

@ -1,54 +1,7 @@
<!doctype html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="utf-8"> {% include default_head_tags.html%}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- HTML Meta Tags -->
<title>Tom Hodson - {{ page.title }}</title>
<meta property="og:title" content="Tom Hodson - {{ page.title }}">
<meta name="twitter:title" content="Tom Hodson - {{ page.title }}">
<meta name="description" content="{{page.excerpt | strip_html | strip}}">
<meta property="og:description" content="{{page.excerpt | strip_html | strip}}">
<meta name="twitter:description" content="{{page.excerpt | strip_html | strip}}">
<meta property="og:url" content="{{site.url}}{{page.url}}">
<meta property="twitter:domain" content="thomashodson.com">
<meta property="twitter:url" content="{{site.url}}{{page.url}}">
<meta property="og:type" content="website">
{% if page.image %}
<meta name="twitter:card" content="{{site.url}}{{page.image}}">
<meta name="twitter:image" content="{{site.url}}{{page.image}}">
<meta property="og:image" content="{{site.url}}{{page.image}}">
{% if page.alt %} <!-- Note og:image:alt must immediately follow og:image tag -->
<meta property="og:image:alt" content="{{page.alt | strip}}">
{% endif %}
{% endif %}
<link rel="stylesheet" href="/assets/css/styles.css">
<script src="/assets/js/index.js"></script>
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
svg: {
fontCache: 'global'
}
};
</script>
<script src="/assets/mathjax/tex-mml-svg.js" id="MathJax-script" async></script>
<!-- RSS feed -->
{% feed_meta %}
</head> </head>
<body> <body>
{% include header.html %} {% include header.html %}

29
_layouts/post_klipse.html Normal file
View File

@ -0,0 +1,29 @@
<!doctype html>
<html>
<head>
{% include default_head_tags.html%}
<!-- For styling the interactive code snippets -->
<link rel="stylesheet" type="text/css" href="/assets/klipse/codemirror.css">
<link rel="stylesheet" type="text/css" href="/assets/klipse/neo.css">
<script>
window.klipse_settings = {
selector_pyodide: '.language-klipse-python', // css selector for the html elements to be klipsified
codemirror_options_in: {
theme: "neo",
},
};
</script>
</head>
<body>
{% include header.html %}
<main>
<h1>{{ page.title }}</h1>
<time>{{ page.date | date_to_string }}</time>
{{ content }}
</main>
<script src="/assets/klipse/klipse_plugin.min.js"></script>
</body>
</html>

View File

@ -3,7 +3,7 @@ title: Parsing is fun!
excerpt: I came across something I wanted to quickly parse that was too niche to find a ready made parser for. Join me on a quick whip tour of writing a grammar for a PEG parser. excerpt: I came across something I wanted to quickly parse that was too niche to find a ready made parser for. Join me on a quick whip tour of writing a grammar for a PEG parser.
layout: post layout: post
image: /assets/blog/parsing/snippet.png image: /assets/blog/parsing/snippet.png
alt: alt: A purely illustrative screenshot of a snippet of python code with a little bit of a PEG grammar definition visible.
--- ---
Usually when I want to parse something so that I can manipulate it in code, be it JSON, YAML, HTML, XML, whatever, there is a nice existing library to do that for me. The solution is a simple `import json` away. However if the language is a bit more niche, there maybe won't be a good parser for it available or that parser might be missing features. Usually when I want to parse something so that I can manipulate it in code, be it JSON, YAML, HTML, XML, whatever, there is a nice existing library to do that for me. The solution is a simple `import json` away. However if the language is a bit more niche, there maybe won't be a good parser for it available or that parser might be missing features.

View File

@ -0,0 +1,34 @@
---
title: A little REPL in every blog post
layout: post_klipse
image:
alt:
---
On someone else's [excellent personal](http://lambdafunk.com/) site I saw [Klipse](https://github.com/viebel/klipse), a little js library that lets you modify and execute code snippets in blogs. How cute!
```klipse-python
print("Hello, world!")
```
There's even a build of python (with the magic of WASM) that includes numpy and pandas!
```klipse-python
import numpy as np
import pandas as pd
np.arange(12).reshape(3,-1)
```
The cells (of a single language) all use the same interpreter so you can share variables across. However this doesn't seem to work when the page first loads.
```klipse-python
import numpy as np
import pandas as pd
a = np.arange(12).reshape(3,-1)
df = pd.DataFrame({"zero" : a[0], "one" : a[2], "twp" : a[2]})
df
```
Hopefully in future this could also hook into the nice html output that many libraries like pandas can produce!

View File

@ -0,0 +1,427 @@
@font-face {
font-family: 'FiraCode';
src: url('FiraCode/woff2/FiraCode-Regular.woff2') format('webfont.woff2') , /* Super Modern Browsers */
url('FiraCode/woff/FiraCode-Regular.woff') format('woff'), /* Pretty Modern Browsers */
url('FiraCode/ttf/FiraCode-Regular.ttf') format('truetype') /* Safari, Android, iOS */;
}
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: 'FiraCode', monospace;
height: 100%;
color: black;
border: solid 1px #90B4FE;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
/* neo theme for codemirror */
/* Color scheme */
.cm-s-neo.CodeMirror {
background-color:#ffffff;
color:#2e383c;
line-height:1.4375;
}
.cm-s-neo .cm-comment { color:#75787b; }
.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; }
.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; }
.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; }
.cm-s-neo .cm-string { color:#b35e14; }
.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; }
/* Editor styling */
.cm-s-neo pre {
padding:0;
}
.cm-s-neo .CodeMirror-gutters {
border:none;
border-right:10px solid transparent;
background-color:transparent;
}
.cm-s-neo .CodeMirror-linenumber {
padding:0;
color:#e0e2e5;
}
.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }
.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }
.cm-s-neo .CodeMirror-cursor {
width: auto;
border: 0;
background: rgba(155,157,162,0.37);
z-index: 1;
}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor { position: absolute; }
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
/* rules for autocompletion add on */
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
.CodeMirror-hint {
margin: 0;
padding: 0 4px;
border-radius: 2px;
white-space: pre;
color: black;
cursor: pointer;
}
li.CodeMirror-hint-active {
background: #08f;
color: white;
}
/* rules for autocompletion add on */

2155
assets/klipse/klipse_plugin.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": "."
}
],
"settings": {}
}