All Downloads are FREE. Search and download functionalities are using the official Maven repository.

knockoff.Discounter.scala Maven / Gradle / Ivy

The newest version!
/*

## Converting Markdown to HTML ##

The `Discounter` is what grabs the "knockoff" of a markdown string. For simple usage,
you can use the `DefaultDiscounter` object.

    import knockoff.DefaultDiscounter._
    toXHTML( knockoff( markdownString ) )

*/
package knockoff

import scala.collection.mutable.ListBuffer
import scala.util.parsing.input.Position
import scala.util.parsing.input.CharSequenceReader

trait Discounter extends ChunkStreamFactory with TextWriter {

  /** Parses and returns our best guess at the sequence of blocks. It will
      never fail, just log all suspicious things. */
  def knockoff(source: java.lang.CharSequence): collection.Seq[Block] = {

    val chunks = createChunkStream(new CharSequenceReader(source, 0))

    // These next lines are really ugly because I couldn't figure out a nice
    // way to match a tuple argument (thank you erasure!)
    val linkDefinitions = chunks.flatMap {
      case ((chunk, pos)) =>
        chunk match {
          case c: LinkDefinitionChunk =>
            c :: Nil
          case _ =>
            Nil
        }
    }

    val convert = createSpanConverter(linkDefinitions)

    val spanned = chunks.map {
      chunkAndPos =>
        (chunkAndPos._1, convert(chunkAndPos._1), chunkAndPos._2)
    }

    combine(spanned.toList, new ListBuffer)
  }

  def createSpanConverter(linkDefinitions: collection.Seq[LinkDefinitionChunk]): SpanConverter =
    new SpanConverter(linkDefinitions)

  /** Consume input and append the right thing to the output until empty. The
      Chunk itself determines the "right thing to do". All chunks only know what
      has come before itself, by peering into the output. (It shouldn't matter
      what comes next...) */
  private def combine(input: List[(Chunk, collection.Seq[Span], Position)],
                      output: ListBuffer[Block])
  : collection.Seq[Block] = {
    input match {
      case h :: t =>
        h._1.appendNewBlock(output, t, h._2, h._3, this)
        combine(input.tail, output)
      case Nil =>
        output
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy