Mercurial > cgi-bin > hgweb.cgi > ClipMan
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/name/blackcap/clipman/Troff.kt Sat Mar 19 23:04:40 2022 -0700 @@ -0,0 +1,78 @@ +/* + * Coercion to troff input. + */ +package name.blackcap.clipman + +import org.jsoup.Jsoup +import org.jsoup.nodes.* +import org.jsoup.select.NodeVisitor + +class Troffizer: NodeVisitor { + private enum class Typeface(val pos: Int) { + ROMAN(1), + ITALIC(2), + BOLD(3) + } + + private val tfStack = mutableListOf<Typeface>(Typeface.ROMAN); + + private val TF_TAGS = mapOf<String, Typeface>( + "em" to Typeface.ITALIC, + "i" to Typeface.ITALIC, + "b" to Typeface.BOLD, + "strong" to Typeface.BOLD) + + private val accum = StringBuilder(); + + override fun head(node: Node, depth: Int): Unit { + when (node) { + is TextNode -> accum.append(node.text()) + is Element -> enterElement(node) + } + } + + override fun tail(node: Node, depth: Int): Unit { + if (node is Element) { + leaveElement(node) + } + } + + private fun enterElement(element: Element) { + var newFace = TF_TAGS[element.normalName()] + if (newFace != null) { + tfStack.add(newFace) + accum.append("\\f") + accum.append(newFace.pos) + } + } + + private fun leaveElement(element: Element) { + if (element.normalName() in TF_TAGS) { + tfStack.removeLast() + accum.append("\\f") + accum.append(tfStack.lastOrNull()?.pos ?: Typeface.ROMAN.pos) + } + } + + fun getTroff(): String = accum.toString() +} + +private fun _troffize(html: String): String { + val troffizer = Troffizer() + Jsoup.parse(html).traverse(troffizer) + return troffizer.getTroff() +} + +fun troffize(item: PasteboardItem): Unit { + val (plain, html) = when (item) { + is PasteboardItem.Plain -> + Pair(item.plain, null) + is PasteboardItem.HTML -> + Pair(item.plain, item.html) + is PasteboardItem.RTF -> + Pair(item.plain, item.html) + } + PasteboardItem.write( + PasteboardItem.Plain( + if (html == null) { plain } else { _troffize(html) })) +}