comparison src/name/blackcap/clipman/Troff.kt @ 56:22725d4d7849

An attempt to get it to troff-ize styled text.
author David Barts <n5jrn@me.com>
date Sat, 19 Mar 2022 23:04:40 -0700
parents
children
comparison
equal deleted inserted replaced
55:7ad2b29a7f60 56:22725d4d7849
1 /*
2 * Coercion to troff input.
3 */
4 package name.blackcap.clipman
5
6 import org.jsoup.Jsoup
7 import org.jsoup.nodes.*
8 import org.jsoup.select.NodeVisitor
9
10 class Troffizer: NodeVisitor {
11 private enum class Typeface(val pos: Int) {
12 ROMAN(1),
13 ITALIC(2),
14 BOLD(3)
15 }
16
17 private val tfStack = mutableListOf<Typeface>(Typeface.ROMAN);
18
19 private val TF_TAGS = mapOf<String, Typeface>(
20 "em" to Typeface.ITALIC,
21 "i" to Typeface.ITALIC,
22 "b" to Typeface.BOLD,
23 "strong" to Typeface.BOLD)
24
25 private val accum = StringBuilder();
26
27 override fun head(node: Node, depth: Int): Unit {
28 when (node) {
29 is TextNode -> accum.append(node.text())
30 is Element -> enterElement(node)
31 }
32 }
33
34 override fun tail(node: Node, depth: Int): Unit {
35 if (node is Element) {
36 leaveElement(node)
37 }
38 }
39
40 private fun enterElement(element: Element) {
41 var newFace = TF_TAGS[element.normalName()]
42 if (newFace != null) {
43 tfStack.add(newFace)
44 accum.append("\\f")
45 accum.append(newFace.pos)
46 }
47 }
48
49 private fun leaveElement(element: Element) {
50 if (element.normalName() in TF_TAGS) {
51 tfStack.removeLast()
52 accum.append("\\f")
53 accum.append(tfStack.lastOrNull()?.pos ?: Typeface.ROMAN.pos)
54 }
55 }
56
57 fun getTroff(): String = accum.toString()
58 }
59
60 private fun _troffize(html: String): String {
61 val troffizer = Troffizer()
62 Jsoup.parse(html).traverse(troffizer)
63 return troffizer.getTroff()
64 }
65
66 fun troffize(item: PasteboardItem): Unit {
67 val (plain, html) = when (item) {
68 is PasteboardItem.Plain ->
69 Pair(item.plain, null)
70 is PasteboardItem.HTML ->
71 Pair(item.plain, item.html)
72 is PasteboardItem.RTF ->
73 Pair(item.plain, item.html)
74 }
75 PasteboardItem.write(
76 PasteboardItem.Plain(
77 if (html == null) { plain } else { _troffize(html) }))
78 }