taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

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 )