blob: 3e0ce17e0d6dec3efa07f44b498f2fccdbc9ab7a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
---
title: A toolset for interacting with character-oriented printers
author:
- "[Gregor Kleen](mailto:gkleen@math.lmu.de)"
date: 2016-01-14
tags: Thermoprint
header-includes:
- \usepackage{hyperref}
- \hypersetup{colorlinks=true}
- \usepackage{enumitem}
- \setlist[description]{style=nextline}
---
This file is an updated version of the [original blog-post](https://dirty-haskell.org/posts/thermoprint-1.html).
# Project description
## Motivation
Some time ago I bought a cheap Chinese
[thermoprinter](https://en.wikipedia.org/wiki/Thermal_printing) off eBay.
As expected the printers firmware is really awkward to use (including binary
control codes used to switch between char sets such as bold, italic, underlined,
etc.).
The obvious solution was to write a library to parse a more sensible
representation and send it to be printed.
Since there might, at some point, be other users wanting to print to my
acquisition the architecture is intended to present a somewhat usable
interface to the uninitiated.
## Implementation
### Location
Recently I created a new branch in
[thermoprint](http://git.yggdrasil.li/thermoprint) called
[rewrite](http://git.yggdrasil.li/thermoprint?h=rewrite).
### Architecture Overview
The new macroscopic architecture I´m currently aiming for is quite similar to
the old one:
* A server intended to run on the machine connected to my cheap printer talking
directly to the printer on one end and serving a
[json api](https://hackage.haskell.org/package/servant) on the other.
* A (hopefully) tiny cli tool for debugging and personal use.
* A website (it will probably end up being based on
[threepenny](https://hackage.haskell.org/package/threepenny-gui)) presenting a web interface
similar to the cli tool.
### Features
Features I intend to implement include:
* A parser for a bbcode-dialect which should be used in both the cli tool and the
website (it will probably end up using
[attoparsec](https://hackage.haskell.org/package/attoparsec)) -- bbcode as
presented on [Wikipedia](https://en.wikipedia.org/wiki/BBCode) is a proper
superset of the feature-set of my cheap Chinese printer.
* Reasonable test coverage using
[QuickCheck](https://hackage.haskell.org/package/QuickCheck),
[HUnit](http://hackage.haskell.org/package/HUnit).
Automatic testing with [cabal](https://www.haskell.org/cabal/) facilitated by
[hspec](https://hackage.haskell.org/package/hspec).
* Support and server-side storage for drafts.
* The Website should provide some richer formats than bbcode which will
probably find inclusion in the payload datastructure such as lists,
checklists, tables, etc.
The cli-tool should be able to use these too (the input will probably end up
being json-formatted).
### Connection to the lecture
We inted to implement:
* A parser using [attoparsec](https://hackage.haskell.org/package/attoparsec))
* A graphical user interface/website using [threepenny](https://hackage.haskell.org/package/threepenny-gui)
* A CLI-tool using [optparse-applicative](https://hackage.haskell.org/package/optparse-applicative)
* A [servant](https://hackage.haskell.org/package/servant) based API
* Some parallelism using [stm](https://hackage.haskell.org/package/stm) for management of printer-queues and the like within the API-backend
Of which only the use of stm was discussed in the lecture.
# Work so far
## Prototype
I already have a prototype.
It's quite bug-ridden and has recently developed serious problems actually
printing after working satisfactorily for a few weeks.
It also does not include a web-interface and I am quite unsatisfied with the
overall code quality.
The [685 lines of code](https://github.com/AlDanial/cloc) can be found in the
[repo](http://git.yggdrasil.li/thermoprint?h=master) as well.
## Rewrite
Currently the [rewrite](http://git.yggdrasil.li/thermoprint?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f) contains:
[Printout.hs](http://git.yggdrasil.li/thermoprint/tree/spec/src/Thermoprint/Printout.hs?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f)
~ A definition of the payload-datatype -- a structured document format meant to be translated into a printer specific representation at print-time
[API.hs](http://git.yggdrasil.li/thermoprint/tree/spec/src/Thermoprint/API.hs?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f)
~ A definition of the API. This already encompasses most of the work on the API due to the powerful derivation utilities provided by servant
[bbcode/src](http://git.yggdrasil.li/thermoprint/tree/bbcode/src/Text?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f)
~ An already complete parser for bbcode -- a format very closely related to xml
*/test
~ [Unit](https://hackage.haskell.org/package/hspec)- and [QuickCheck](https://hackage.haskell.org/package/QuickCheck)-tests for:
* The smart constructor [`text`](http://git.yggdrasil.li/thermoprint/tree/spec/src/Thermoprint/Printout.hs?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f#n131) for [`Block`](http://git.yggdrasil.li/thermoprint/tree/spec/src/Thermoprint/Printout.hs?h=rewrite&id=1cc1bc4555d1ca7688920027b401ea94f3b82d5f#n83).
* The To- and FromJSON instances of `Printout`
* The [bbcode lexer](http://git.yggdrasil.li/thermoprint/tree/bbcode/src/Text/BBCode/Lexer.hs?h=rewrite)
* The entire [bbcode parser](http://git.yggdrasil.li/thermoprint/tree/bbcode/src/Text/BBCode.hs?h=rewrite)
|