TosSection.kt (2955B)
1 /* 2 * This file is part of GNU Taler 3 * (C) 2020 Taler Systems S.A. 4 * 5 * GNU Taler is free software; you can redistribute it and/or modify it under the 6 * terms of the GNU General Public License as published by the Free Software 7 * Foundation; either version 3, or (at your option) any later version. 8 * 9 * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 package net.taler.wallet.withdraw 18 19 import io.noties.markwon.Markwon 20 import kotlinx.serialization.Serializable 21 import org.commonmark.node.Code 22 import org.commonmark.node.Document 23 import org.commonmark.node.Heading 24 import org.commonmark.node.Node 25 import org.commonmark.node.Text 26 import java.text.ParseException 27 28 data class TosSection( 29 val title: String?, 30 val node: Node, 31 var expanded: Boolean = false 32 ) 33 34 @Throws(ParseException::class) 35 internal fun parseTos(markwon: Markwon, text: String): List<TosSection> { 36 val rootNode: Node = markwon.parse(text) 37 var node: Node? = rootNode.firstChild 38 ?: throw ParseException("Invalid markdown", 0) 39 var lastHeading: String? = null 40 var section = Document() 41 val sections = ArrayList<TosSection>() 42 while (node != null) { 43 val next: Node? = node.next 44 // TODO: better sectioning logic! level 1+2 is a hack 45 if (node is Heading && (node.level == 1 || node.level == 2)) { 46 // if lastHeading exists, close previous section 47 if (lastHeading != null) { 48 sections.add(TosSection(lastHeading, section)) 49 section = Document() 50 } 51 // start new section with new heading (stripped of markup) 52 lastHeading = getNodeText(node) 53 if (lastHeading.isBlank()) { 54 return listOf(TosSection(null, rootNode, true)) 55 } 56 } else if (lastHeading == null) { 57 return listOf(TosSection(null, rootNode, true)) 58 } else { 59 section.appendChild(node) 60 } 61 node = next 62 } 63 check(lastHeading != null) 64 sections.add(TosSection(lastHeading, section)) 65 return sections 66 } 67 68 private fun getNodeText(rootNode: Node): String { 69 var node: Node? = rootNode.firstChild 70 var text = "" 71 while (node != null) { 72 text += when (node) { 73 is Text -> node.literal 74 is Code -> node.literal 75 else -> getNodeText(node) 76 } 77 node = node.next 78 } 79 return text 80 } 81 82 @Serializable 83 data class TosResponse( 84 val content: String, 85 val currentEtag: String, 86 val contentLanguage: String? = null, 87 val tosAvailableLanguages: List<String> = emptyList(), 88 )