aboutsummaryrefslogtreecommitdiff
path: root/plugins/base/src/main/kotlin/renderers/html/htmlFormatingUtils.kt
blob: b6ce4147b4ca8d82dffd4737dfb77527a387e8e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
 * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package org.jetbrains.dokka.base.renderers.html

import kotlinx.html.FlowContent
import kotlinx.html.span

public fun FlowContent.buildTextBreakableAfterCapitalLetters(name: String, hasLastElement: Boolean = false) {
    if (name.contains(" ")) {
        val withOutSpaces = name.split(" ")
        withOutSpaces.dropLast(1).forEach {
            buildBreakableText(it)
            +" "
        }
        buildBreakableText(withOutSpaces.last())
    } else {
        val content = name.replace(Regex("(?<=[a-z])([A-Z])"), " $1").split(" ")
        joinToHtml(content, hasLastElement) {
            it
        }
    }
}

public fun FlowContent.buildBreakableDotSeparatedHtml(name: String) {
    val phrases = name.split(".")
    phrases.forEachIndexed { i, e ->
        val elementWithOptionalDot = e.takeIf { i == phrases.lastIndex } ?: "$e."
        if (e.length > 10) {
            buildTextBreakableAfterCapitalLetters(elementWithOptionalDot, hasLastElement = i == phrases.lastIndex)
        } else {
            buildBreakableHtmlElement(elementWithOptionalDot, i == phrases.lastIndex)
        }
    }
}

private fun FlowContent.joinToHtml(elements: List<String>, hasLastElement: Boolean = true, onEach: (String) -> String) {
    elements.dropLast(1).forEach {
        buildBreakableHtmlElement(onEach(it))
    }
    elements.takeIf { it.isNotEmpty() && it.last().isNotEmpty() }?.let {
        if (hasLastElement) {
            span {
                buildBreakableHtmlElement(it.last(), last = true)
            }
        } else {
            buildBreakableHtmlElement(it.last(), last = false)
        }
    }
}

private fun FlowContent.buildBreakableHtmlElement(element: String, last: Boolean = false) {
    element.takeIf { it.isNotBlank() }?.let {
        span {
            +it
        }
    }
    if (!last) {
        wbr { }
    }
}

public fun FlowContent.buildBreakableText(name: String) {
    if (name.contains(".")) buildBreakableDotSeparatedHtml(name)
    else buildTextBreakableAfterCapitalLetters(name, hasLastElement = true)
}