♻️ Copy session-handling code to FreenetRequest
[Sone.git] / src / main / kotlin / net / pterodactylus / sone / template / ShortenFilter.kt
1 package net.pterodactylus.sone.template
2
3 import net.pterodactylus.sone.text.LinkPart
4 import net.pterodactylus.sone.text.Part
5 import net.pterodactylus.sone.text.PlainTextPart
6 import net.pterodactylus.util.template.Filter
7 import net.pterodactylus.util.template.TemplateContext
8 import java.util.*
9
10 /**
11  * [Filter] that shortens a number of [Part]s in order to restrict the maximum visible text length.
12  */
13 class ShortenFilter : Filter {
14
15         override fun format(templateContext: TemplateContext?, data: Any?, parameters: Map<String, Any?>?): Any? {
16                 @Suppress("UNCHECKED_CAST")
17                 val parts = data as? Iterable<Part> ?: return null
18                 val length = parameters?.parseInt("length") ?: -1
19                 val cutOffLength = parameters?.parseInt("cut-off-length") ?: length
20                 if (length > -1) {
21                         var allPartsLength = 0
22                         val shortenedParts = ArrayList<Part>()
23                         for (part in parts) {
24                                 if (part is PlainTextPart) {
25                                         val longText = part.text
26                                         if (allPartsLength < cutOffLength) {
27                                                 if (allPartsLength + longText.length > cutOffLength) {
28                                                         shortenedParts.add(PlainTextPart(longText.substring(0, cutOffLength - allPartsLength) + "…"))
29                                                 } else {
30                                                         shortenedParts.add(part)
31                                                 }
32                                         }
33                                         allPartsLength += longText.length
34                                 } else if (part is LinkPart) {
35                                         if (allPartsLength < cutOffLength) {
36                                                 shortenedParts.add(part)
37                                         }
38                                         allPartsLength += part.text.length
39                                 } else {
40                                         if (allPartsLength < cutOffLength) {
41                                                 shortenedParts.add(part)
42                                         }
43                                 }
44                         }
45                         if (allPartsLength > length) {
46                                 return shortenedParts
47                         }
48                 }
49                 return parts
50         }
51
52         private fun Map<String, Any?>.parseInt(key: String) = this[key]?.toString()?.toInt()
53
54 }