Mercurial > cgi-bin > hgweb.cgi > ClipMan
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 } |