add emscripten target

This commit is contained in:
Jeff Epler 2016-05-15 14:43:24 -05:00
parent eea9fcd427
commit b5321c7ed3
5 changed files with 145 additions and 2 deletions

8
.gitignore vendored
View file

@ -1,2 +1,6 @@
ana
dict.bin
/ana
/ana.js
/ana.js.mem
/anamodule.so
/dict.bin
/words

View file

@ -33,8 +33,18 @@ CXXFLAGS := -g $(call cc-option,-std=c++11,-std=c++0x) -Wall
all: ana anamodule.so
ana.js: $(wildcard *.cc) $(wildcard *.h) Makefile words
em++ -Os --bind -std=c++11 -s TOTAL_MEMORY=33554432 --embed-file words -DANA_AS_JS run.cc -o ana.js
words:
grep '^[a-z]*$$' /usr/share/dict/words > $@
ana: $(wildcard *.cc) $(wildcard *.h) Makefile
$(CXX) $(CXXFLAGS) -fwhole-program -o $@ $(filter %.cc, $^)
anamodule.so: $(wildcard *.cc) $(wildcard *.h) Makefile
$(CXX) $(CXXFLAGS) $(CXXFLAGS_PYTHON) -o $@ $(filter %.cc, $^) \
$(LFLAGS_PYTHON)
publish: ana.js ana.html ana.js.mem
git branch -D gh-pages || true
./import ana.js ana.js.mem index.html=ana.html | git fast-import --date-format=now

67
ana.html Normal file
View file

@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<head>
<title>Surly Anagram Server (emscripted)</title>
<style>
@media screen and (min-width: 680px) { #cheatsheet { float: right; } }
#cheatsheet { font-size: 71%; cursor: pointer; }
#cheatsheet table, #cheatsheet caption { background: #d9d9d9; color: #000; }
#cheatsheet.hidden { cursor: zoom-in; }
#cheatsheet caption:after { content: "«" }
#cheatsheet.hidden caption:after { content: "»" }
#cheatsheet.hidden tbody { display: none; }
//#cheatsheet { float: right; }
#cheatsheet th { text-align: left }
#cheatsheet caption { font-weight: bold; }
</style>
</head>
<body>
<div id="cheatsheet"
onclick="document.getElementById('cheatsheet').classList.toggle('hidden')">
<table>
<caption>Cheatsheet</caption>
<tr><th>letters... <td> Letters available to anagram
<tr><th>=word <td> word must be in result
<tr><th>&gt;n <td> words must contain at least n letters
<tr><th>&lt;n <td> words must contain at most n letters
<tr><th>' <td> words with apostrophes are considered
<tr><th>n <td> choose a word with exactly n letters
<tr><th>-n <td> display at most n results (limit 1000)
<tr><th>? <td> display candidate words, not whole phrases
<tr><td colspan=2>In ajax mode, hit enter or click "anagram" to do get full results
<tr><td colspan=2>Source (web app and unix commandline program) on
<a href="https://github.com/jepler/anagram">github</a>
</table>
</div>
<form id="f" onsubmit="javascript:update();return false"><input type="text" id="query" name="q" value="" oninput="javascript:update()">
</form>
<pre id="results">
<script>
var last = '';
var Module;
if(typeof Module==="undefined") Module={};
Module['onRuntimeInitialized'] = function() {
update = function() {
var search = document.getElementById("query").value;
document.location.hash = '#' + search;
if(search == last) return false;;
document.getElementById("results").innerText=Module.ana(search);
last = search;
return false;
}
if(document.location.hash) {
document.getElementById("query").value = decodeURIComponent(
document.location.hash.substr(1));
update();
}
}
</script>
<script src="ana.js"></script>
<script>
document.getElementById("query").focus()
</script>
</body>
</html>

37
import Executable file
View file

@ -0,0 +1,37 @@
#!/usr/bin/python3
import argparse
import glob
import os
import subprocess
import sys
parser = argparse.ArgumentParser()
parser.add_argument("--branch", metavar='branch', default="gh-pages",
help="branch to use (any old contents are destroyed)")
parser.add_argument('files', metavar='files', nargs='+',
help='files to be committed')
args = parser.parse_args()
version = subprocess.getoutput("git describe --always --dirty")
fd = os.fdopen(sys.stdout.fileno(), 'wb')
fd.write(b"commit refs/heads/" + args.branch.encode('utf-8') + b"\n")
fd.write(b"committer Doc Man <noreply@example.com> now" + b"\n")
fd.write(b"data <<EOF" + b"\n")
fd.write(b"Docs built at " + version.encode('utf-8') + b"\n")
fd.write(b"EOF" + b"\n")
for fn in args.files:
if '=' in fn:
dest, src = fn.split('=', 1)
else:
dest = src = fn
with open(src, 'rb') as f: contents = f.read()
fd.write(b"M 644 inline " + os.path.basename(dest).encode('utf-8') + b"\n")
fd.write(b"data " + str(len(contents)).encode("utf-8") + b"\n")
fd.write(contents)
fd.write(b"done\n")

25
run.cc
View file

@ -718,6 +718,31 @@ initana(void) {
PyModule_AddObject(m, "anadict", (PyObject *)&dict_type);
}
#elif defined(ANA_AS_JS)
#include <emscripten/bind.h>
dict d;
std::string js_run(std::string s) {
std::string result;
ana_cfg cfg;
ana_st st;
parse(s, cfg, false, false, 3, 11, 1000);
setup(st, cfg, d);
while(1) {
std::string line;
bool res = step(st, line);
result += line; result += "\n";
if(!res) break;
}
return result;
}
EMSCRIPTEN_BINDINGS(ana) {
emscripten::function("ana", &js_run);
d.readdict("words");
}
#else
int main(int argc, char **argv)
{