Skip to content

Latest commit

 

History

History
133 lines (101 loc) · 3.44 KB

package.scala.md

File metadata and controls

133 lines (101 loc) · 3.44 KB

Working with files

package laughedelic.literator

import java.io._
import java.nio.file.Path

import lib.LanguageMap._
import lib.FileUtils._

package object lib {

  implicit class FileLiterator(root: File) {

Checks that the file has a known source format

    def isSource: Boolean = langMap.isDefinedAt(root.ext)
    def isMarkdown: Boolean = root.ext match {
      case "md" | "mkd" | "mdown" | "markdown" => true
      case _ => false
    }

This is the key function. If the source file is a directory, it traverses it, takes all children, parses each and writes a correcponding markdown file. If parser encounters some errors, it returns them in a list.

    def literate(
          destBase: Option[File] = None
        , withIndex: Boolean = true
        ): List[String] = {

First we can generate index section

      val index = root getFileTree { f => f.isDirectory || f.isSource } match {
          case Some(ix) if withIndex => Seq("------", "### Index", ix) mkString "\n\n"
          case _ => ""
        }

Then we start with traversing list of source files

      val fileList = root getFileList { f => f.isSource || f.isMarkdown }

      def writeResult(source: File, name: String, text: String): Unit = {
        destBase map { base =>
          val relative: Path = source.getCanonicalFile.getParentFile.relativePath(root)
          val destDir: File = new File(base.getCanonicalFile, relative.toString)
          if (!destDir.exists) destDir.mkdirs
          new File(destDir, name).write(text) 
        }
      }

      // TODO: this code is bad structured: look at all those } } } in the end... 
      fileList flatMap { child =>

And for each of them we generate a block of relative links

        val linksList = fileList map { f =>
            "["+f.relativePath(root).toString+"]: "+f.relativePath(child).toString+".md"
          } mkString("\n")

        child.ext match {
          case "md" | "mkd" | "mdown" | "markdown" => {
            val text = Seq(child.read, linksList) mkString "\n\n"
            writeResult(child, child.name, text)
            None
          }
          case _ => {

            langMap.get(child.ext) flatMap { lang =>

Knowing the language of the source we can parse it

              val literator = LiteratorParsers(lang)
              val parsed = literator.parseAll(literator.markdown, child.read) 

              parsed match {
                case literator.NoSuccess(msg, _) => Some(s"${child} ${parsed}")
                case literator.Success(result, _) => {
                  val text = Seq(result, index, linksList) mkString "\n\n"

And if we parsed something, we write it to the file

                  writeResult(child, child.name+".md", text)
                  None
                }
              }
            }
          }
        }
      }
    }
  }
}


Index