diff --git a/.gitignore b/.gitignore
index 9731313..a91e699 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,6 @@ npm-debug.log
/priv/avatar/
/priv/repo/dumps/
/priv/static/
+
+/size
+/size.o
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..21d2b17
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+
+PROG = size
+SRC = size.c
+SRC_O = size.o
+
+all: ${PROG}
+
+${PROG}: ${SRC_O}
+ ${CC} ${CFLAGS} ${LDFLAGS} ${SRC_O} ${LIBS} -o ${PROG}
+
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $< -o $@
+
+clean:
+ rm -f ${SRC_O} ${PROG}
+
+.PHONY: all clean
diff --git a/lib/pygmentize.ex b/lib/pygmentize.ex
index 85e506d..da39dd8 100644
--- a/lib/pygmentize.ex
+++ b/lib/pygmentize.ex
@@ -5,31 +5,41 @@ defmodule Pygmentize do
|> Base.url_encode64()
end
- def html(content, filename) do
- dir = "#{System.tmp_dir()}/#{random_string()}"
- File.mkdir_p(dir)
- path = "#{dir}/#{filename}"
- File.write(path, content)
- {out, status} = System.cmd("pygmentize", ["-f", "html", path], stderr_to_stdout: true)
- output = case status do
- 0 -> out
- _ -> nil
+ def lexer(filename) do
+ {out, status} = System.cmd("pygmentize", ["-N", filename |> String.replace(~r/ /, "_")])
+ case status do
+ 0 -> out |> String.trim()
+ _ -> ""
end
- File.rm_rf(dir)
- output
+ end
+
+ def html(content, filename) do
+ lexer = lexer(filename)
+ cmd = "./size #{byte_size(content)} pygmentize -l #{lexer} -f html"
+ IO.inspect(cmd)
+ port = Port.open({:spawn, cmd}, [:binary, :use_stdio, :exit_status, :stderr_to_stdout])
+ Port.monitor(port)
+ send(port, {self(), {:command, content}})
+ html_port(content, port, [])
end
- def get_reply(port, state) do
- ref = state.ref
+ def html_port(content, port, acc) do
receive do
- {^port, {:data, msg}} ->
- state = Map.put(state, :content, [msg | state.content])
- get_reply(port, state)
- {:DOWN, ^ref, :port, _port, :normal} ->
- Enum.reverse(state.output)
- msg ->
- IO.inspect([msg: msg])
- get_reply(port, state)
+ {^port, {:exit_status, 0}} ->
+ acc |> Enum.reverse() |> Enum.join()
+ {^port, {:exit_status, status}} ->
+ IO.inspect("pygmentize exited with status #{status}")
+ content
+ {^port, {:data, data}} ->
+ html_port(content, port, [data | acc])
+ {:DOWN, _, :port, ^port, reason} ->
+ IO.inspect({:down, reason})
+ acc |> Enum.reverse() |> Enum.join()
+ x ->
+ IO.inspect(x)
+ html_port(content, port, acc)
+ after 1000 ->
+ html_port(content, port, acc)
end
end
end
diff --git a/size.c b/size.c
new file mode 100644
index 0000000..37c0852
--- /dev/null
+++ b/size.c
@@ -0,0 +1,50 @@
+/* size - truncate standard input by size */
+
+#include <err.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BUFSIZE 8192
+
+int usage(char *argv0)
+{
+ fprintf(stderr, "Usage: %s SIZE COMMAND [ARGS ...]\n", argv0);
+ return 1;
+}
+
+int main (int argc, char **argv)
+{
+ char *a;
+ char cmd[BUFSIZE];
+ char *c = cmd;
+ char buf[BUFSIZE];
+ int i = 0;
+ size_t pos = 0;
+ ssize_t r;
+ unsigned long size;
+ FILE *pipe;
+ size_t len;
+ if (argc < 3)
+ return usage(argv[0]);
+ size = strtoul(argv[1], NULL, 10);
+ for (i = 2; i < argc; i++) {
+ a = argv[i];
+ while ((*c++ = *a++))
+ ;
+ c--;
+ *c++ = ' ';
+ }
+ *c = 0;
+ pipe = popen(cmd, "w");
+ len = pos + BUFSIZE < size ? BUFSIZE : size - pos;
+ while (pos < size && (r = fread(buf, 1, len, stdin)) > 0) {
+ if (fwrite(buf, r, 1, pipe) != 1)
+ err(1, "fwrite");
+ pos += r;
+ }
+ if (r < 0)
+ err(1, "fread");
+ pclose(pipe);
+ return 0;
+}