Add esc_printer_actor
This commit is contained in:
parent
1bf29bdf02
commit
32f8cd792c
33
README.md
33
README.md
|
@ -241,6 +241,39 @@ Examples:
|
|||
|
||||
---
|
||||
|
||||
## esc_printer_actor
|
||||
|
||||
A basic [ESC/P](https://en.wikipedia.org/wiki/ESC/P) printer controller.
|
||||
|
||||
Takes a path to a printer device file as a command line argument and publishes a `<printer @cap #:any @device-path string>` to its environment.
|
||||
The capability in this assertion is an entity that prints the strings it receives as messages.
|
||||
While the `<bold>` or `<italic>` is asserted to this entity the printer will go into the corresponding font mode (if the printer supports it).
|
||||
|
||||
Sample Syndicate server script:
|
||||
```
|
||||
<require-service <daemon printer>>
|
||||
|
||||
? <printer ?printer> [
|
||||
$log ?? <log "-" { line: ?line }> [
|
||||
$printer ! $text
|
||||
$printer ! "\r\n"
|
||||
# Print log messages.
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
? <service-object <daemon printer> ?cap> [
|
||||
$cap ? <printer ?printer ?device> [
|
||||
$config <printer $printer>
|
||||
]
|
||||
]
|
||||
|
||||
<daemon printer {
|
||||
argv: [ "/bin/esc_printer_actor" "/dev/usb/lp0"]
|
||||
protocol: application/syndicate
|
||||
}>
|
||||
```
|
||||
|
||||
## http_client
|
||||
|
||||
The inverse of `http-driver`.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"bom-ref": "pkg:nim/syndicate_utils",
|
||||
"name": "syndicate_utils",
|
||||
"description": "Utilites for Syndicated Actors and Synit",
|
||||
"version": "20240523",
|
||||
"version": "20240530",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emery Hemingway"
|
||||
|
@ -41,6 +41,10 @@
|
|||
"name": "nim:bin:mintsturdyref",
|
||||
"value": "mintsturdyref"
|
||||
},
|
||||
{
|
||||
"name": "nim:bin:esc-printer-actor",
|
||||
"value": "esc_printer_actor"
|
||||
},
|
||||
{
|
||||
"name": "nim:bin:msg",
|
||||
"value": "msg"
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
||||
# SPDX-License-Identifier: Unlicense
|
||||
|
||||
## ESC/P printer control actor.
|
||||
|
||||
import
|
||||
std/[cmdline, oserrors, posix, sets],
|
||||
preserves, preserves/sugar,
|
||||
syndicate, syndicate/relays,
|
||||
./private/esc_p
|
||||
|
||||
proc echo(args: varargs[string, `$`]) {.used.} =
|
||||
stderr.writeLine(args)
|
||||
|
||||
type
|
||||
HandleSet = HashSet[Handle]
|
||||
|
||||
Printer = ref object of Entity
|
||||
device: cint
|
||||
boldHandles, italicHandles, superscriptHandles, subscriptHandles: HandleSet
|
||||
|
||||
proc write(printer: Printer; s: string) {.inline.} =
|
||||
if posix.write(printer.device, s[0].addr, s.len) < 0:
|
||||
osLastError().osErrorMsg().quit()
|
||||
|
||||
proc writeLine(printer: Printer; s: string) {.inline.} =
|
||||
printer.write(s)
|
||||
printer.write("\r\n")
|
||||
|
||||
method message(printer: Printer; t: Turn; a: AssertionRef) =
|
||||
if a.value.isString:
|
||||
printer.write(a.value.string)
|
||||
# TODO: unicode?
|
||||
# TODO: line breaks?
|
||||
|
||||
proc assert(printer: Printer; handles: var HandleSet; ctrl: string; h: Handle) =
|
||||
if handles.len == 0: printer.write(ctrl)
|
||||
handles.incl h
|
||||
|
||||
proc retract(printer: Printer; handles: var HandleSet; ctrl: string; h: Handle) =
|
||||
handles.excl h
|
||||
if handles.len == 0: printer.write(ctrl)
|
||||
|
||||
method publish(printer: Printer; t: Turn; a: AssertionRef; h: Handle) =
|
||||
if a.value.isRecord("bold"):
|
||||
printer.assert(printer.boldHandles, SelectBoldFont, h)
|
||||
|
||||
elif a.value.isRecord("italic"):
|
||||
printer.assert(printer.italicHandles, SelectItalicFont, h)
|
||||
|
||||
elif a.value.isRecord("superscript"):
|
||||
printer.assert(printer.superscriptHandles, SelectSuperScript, h)
|
||||
|
||||
elif a.value.isRecord("subscript"):
|
||||
printer.assert(printer.subscriptHandles, SelectSubScript, h)
|
||||
|
||||
method retract(printer: Printer; t: Turn; h: Handle) =
|
||||
if printer.boldHandles.contains h:
|
||||
printer.retract(printer.boldHandles, CancelBoldFont, h)
|
||||
|
||||
elif printer.italicHandles.contains h:
|
||||
printer.retract(printer.italicHandles, CanceItalicFont, h)
|
||||
|
||||
elif printer.superscriptHandles.contains h:
|
||||
printer.retract(printer.superscriptHandles, CancelAltScript, h)
|
||||
|
||||
elif printer.subscriptHandles.contains h:
|
||||
printer.retract(printer.subscriptHandles, CancelAltScript, h)
|
||||
|
||||
proc openPrinter(turn: Turn; devicePath: string): Printer =
|
||||
new result
|
||||
result.facet = turn.facet
|
||||
result.device = posix.open(devicePath, O_WRONLY, 0)
|
||||
result.write(InitializePrinter)
|
||||
|
||||
proc main =
|
||||
let devicePath = paramStr(1)
|
||||
runActor(devicePath) do (turn: Turn):
|
||||
let printer = turn.newCap openPrinter(turn, devicePath)
|
||||
resolveEnvironment(turn) do (turn: Turn; ds: Cap):
|
||||
publish(turn, ds, initRecord(
|
||||
toSymbol"printer", printer.embed, %devicePath))
|
||||
|
||||
main()
|
|
@ -0,0 +1,11 @@
|
|||
const
|
||||
ESC* = "\x1b"
|
||||
InitializePrinter* = ESC & "@"
|
||||
CancelLine* = ESC & "\x18"
|
||||
SelectBoldFont* = ESC & "E"
|
||||
CancelBoldFont* = ESC & "F"
|
||||
SelectItalicFont* = ESC & "4"
|
||||
CanceItalicFont* = ESC & "5"
|
||||
SelectSuperScript* = ESC & "S0"
|
||||
SelectSubScript* = ESC & "S1"
|
||||
CancelAltScript* = ESC & "T"
|
Loading…
Reference in New Issue