<commit_before>package com.seanshubin.detangler.report

import com.seanshubin.detangler.model.{Detangled, Standalone}

import scala.annotation.tailrec

class TableOfContentsTemplateRulesImpl(detangled: Detangled) extends TableOfContentsTemplateRules {
  override def generate(template: HtmlElement): HtmlElement = {
    val empty = template.remove(".table-of-contents-row")
    val rowTemplate = template.select(".table-of-contents-row")

    def appendChild(appendToMe: HtmlElement, child: Standalone): HtmlElement = {
      val text = standaloneToText(child)
      val row = rowTemplate.anchor(".link", HtmlRender.absoluteModuleLink(child), text)
      appendToMe.append("#table-of-contents-body", row)
    }

    val children = detangled.allStandalone()
    children.foldLeft(empty)(appendChild)
  }

  private def standaloneToText(standalone: Standalone): String = {
    standaloneToTextRecursive(Nil, standalone)
  }

  @tailrec
  private def standaloneToTextRecursive(soFar: List[String], standalone: Standalone): String = {
    if (standalone.isRoot) {
      soFar.mkString(".")
    } else {
      val text = HtmlRender.reportPageLinkName(standalone)
      standaloneToTextRecursive(text :: soFar, standalone.parent)
    }
  }
}<commit_msg>Broke table of contents into levels<commit_after>package com.seanshubin.detangler.report

import com.seanshubin.detangler.model.{Detangled, Standalone}

import scala.annotation.tailrec

class TableOfContentsTemplateRulesImpl(detangled: Detangled) extends TableOfContentsTemplateRules {
  override def generate(template: HtmlElement): HtmlElement = {
    val empty = template.remove(".table-of-contents-row")
    val rowTemplate = template.select(".table-of-contents-row").remove(".table-of-contents-cell")
    val cellTemplate = template.select(".table-of-contents-cell")

    def appendChild(appendToMe: HtmlElement, standalone: Standalone): HtmlElement = {
      val cells = standaloneToCells(cellTemplate, standalone)
      val row = rowTemplate.append(".table-of-contents-row", cells)
      appendToMe.append("#table-of-contents-body", row)
    }

    val children = detangled.allStandalone()
    children.foldLeft(empty)(appendChild)
  }


  private def standaloneToCells(cellTemplate:HtmlElement, standalone: Standalone): Seq[HtmlElement] = {
    standaloneToCellsRecursive(Nil, cellTemplate, standalone)
  }

  @tailrec
  private def standaloneToCellsRecursive(soFar: List[HtmlElement], cellTemplate:HtmlElement, standalone: Standalone): Seq[HtmlElement] = {
    if (standalone.isRoot) {
      soFar
    } else {
      val text = HtmlRender.reportPageLinkName(standalone)
      val href = HtmlRender.absoluteModuleLink(standalone)
      val cell = cellTemplate.anchor(".link", href, text)
      standaloneToCellsRecursive(cell :: soFar, cellTemplate, standalone.parent)
    }
  }
}
{'fraction_non_alphanumeric': 0.10793650793650794, 'fraction_numerical': 0.0, 'mean_word_length': 4.694779116465863, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7155457', 'n_tokens_mistral': 862, 'n_tokens_neox': 827, 'n_words': 156}