summaryrefslogtreecommitdiff
path: root/provider/posts/thermoprint/1.md
diff options
context:
space:
mode:
Diffstat (limited to 'provider/posts/thermoprint/1.md')
-rw-r--r--provider/posts/thermoprint/1.md130
1 files changed, 130 insertions, 0 deletions
diff --git a/provider/posts/thermoprint/1.md b/provider/posts/thermoprint/1.md
new file mode 100644
index 0000000..032e2f6
--- /dev/null
+++ b/provider/posts/thermoprint/1.md
@@ -0,0 +1,130 @@
1---
2title: On the Architecture of a tool-set for interacting with character-oriented printers
3published: 2015-12-25
4tags: Thermoprint
5---
6
7# Motivation
8
9Some time ago I bought a cheap Chinese
10[thermoprinter](https://en.wikipedia.org/wiki/Thermal_printing) off eBay.
11As expected the printers firmware is really awkward to use (including binary
12control codes used to switch between char sets such as bold, italic, underlined,
13etc.).
14The obvious solution was to write a library to parse a more sensible
15representation and send it to be printed.
16
17Since there might, at some point, be other users wanting to print to my
18acquisition the architecture is intended to be present a somewhat usable
19interface to the uninitiated.
20
21# Implementation
22
23## Location
24
25Recently I created a new branch in
26[thermoprint](https://git.yggdrasil.li/thermoprint) called
27[rewrite](https://git.yggdrasil.li/thermoprint?h=rewrite).
28
29## Architecture Overview
30
31The new macroscopic architecture I´m currently aiming for is quite similar to
32the old one:
33
34 * A server intended to run on the machine connected to my cheap printer talking
35 directly to the printer on one end and serving a
36 [json api](https://hackage.haskell.org/package/servant) on the other.
37 * A (hopefully) tiny cli tool for debugging and personal use.
38 * A website (it will probably end up being based on
39 [yesod](https://hackage.haskell.org/package/yesod)) presenting a web interface
40 similar to the cli tool.
41
42## Features
43
44Features I intend to implement include:
45
46 * A parser for a bbcode-dialect which should be used in both the cli tool and the
47 website (it will probably end up using
48 [attoparsec](https://hackage.haskell.org/package/attoparsec)) -- bbcode as
49 presented on [Wikipedia](https://en.wikipedia.org/wiki/BBCode) is a proper
50 superset of the feature-set of my cheap Chinese printer.
51 * Reasonable test coverage using
52 [QuickCheck](https://hackage.haskell.org/package/QuickCheck),
53 [HUnit](http://hackage.haskell.org/package/HUnit).
54
55 Automatic testing with [cabal](https://www.haskell.org/cabal/) facilitated by
56 [hspec](https://hackage.haskell.org/package/hspec).
57 * Support and server-side storage for drafts.
58 * The Website should provide some richer formats than bbcode which will
59 probably find inclusion in the payload datastructure such as lists,
60 checklists, tables, etc.
61
62 The cli-tool should be able to use these too (the input will probably end up
63 being json-formatted).
64
65## Work so far
66
67### Prototype
68
69I already have a prototype.
70It's quite bug-ridden and has recently developed serious problems actually
71printing after working satisfactorily for a few weeks.
72
73It also does not include a web-interface and I am quite unsatisfied with the
74overall code quality.
75
76The [685 lines of code](http://cloc.sourceforge.net/) can be found in the
77[repo](https://git.yggdrasil.li/thermoprint?h=master) as well.
78
79### Rewrite
80
81Currently the [rewrite](https://git.yggdrasil.li/thermoprint?h=rewrite) contains a
82single file of moment -- spec/src/Thermoprint/Printout.hs -- wherein we define
83the payload for the api -- our take on a structured document format (somewhat
84inspired by
85[pandoc](http://hackage.haskell.org/package/pandoc-types/docs/Text-Pandoc-Definition.html)):
86
87~~~ {.haskell}
88-- | A 'Printout' is a sequence of visually seperated 'Paragraph's
89type Printout = Seq Paragraph
90
91-- | A 'Paragraph' is a non-seperated sequence of 'Chunk's
92type Paragraph = Seq Chunk
93
94-- | We introduce both 'Chunk' and 'Paragraph' mainly to allow 'Raw'.
95--
96-- Were we to disallow 'Raw', 'Block' would be identical to 'Paragraph'
97data Chunk = Cooked Block -- ^ text semantically structured to be rendered in accordance with the display format of printer
98 | Raw ByteString -- ^ direct instructions to the printer
99 deriving (Generic, NFData, Show, CoArbitrary)
100
101-- | 'Block' is the entry point for our structured document format
102data Block = Line Line -- ^ a single 'Line' of text
103 | VSpace Integer -- ^ vertical space of height equivalent to 'Integer' lines
104 | NewlSep (Seq Block) -- ^ A sequence of 'Block's seperated by newlines
105 deriving (Generic, NFData, Show, CoArbitrary)
106
107{- | A 'Line' is one of:
108
109 * a single word
110 * horizontal space equivalent to the width of 'Integer' `em`.
111 * a sequence of words seperated by spaces
112
113We don't export all constructors and instead encourage the use of 'text'.
114-}
115data Line = Word Text
116 | HSpace Integer
117 | SpaceSep (Seq Line)
118 deriving (Generic, NFData, Show, CoArbitrary)
119~~~
120
121(The code is verbatim as of 8307d7e).
122
123<!-- LocalWords: Thermoprint thermoprint json api cli yesod bbcode attoparsec
124 -->
125<!-- LocalWords: superset QuickCheck HUnit hspec datastructure repo pandoc
126 -->
127<!-- LocalWords: haskell ByteString NFData CoArbitrary VSpace
128 -->
129<!-- LocalWords: NewlSep HSpace SpaceSep
130 -->