Scala 㧠markdown ãã¼ã¹ããã ãã§ã¯ãªããåºåãå°ãããã
åå knockoff ãªãã©ã¤ãã©ãªãç´¹ä»ããã®ã§ãããã¡ããã£ã¨å 容ãå¤æ´ãã¦ã¿ã¾ãã knockoff ã§ãã¼ã¹ããåã¨ããã®ã¯
def knockoff( source : java.lang.CharSequence ) : Seq[Block] = {
ãªãã¦å®ç¾©ã«ãªã£ã¦ãããè¦ã¯ Block ã¨å¼ã°ãã解æãã¼ã¿ã®ã·ã¼ã±ã³ã¹ã§ããã¨ã ã§ããã°ããã®åãåããã°å¿ ç¶çã«åºåçµæãå¼ããããã§ãã½ã¼ã¹ã追ããããã
trait Block { def position : Position } case class Paragraph( spans : Seq[Span], position : Position ) extends Block case class Header( level : Int, spans : Seq[Span], position : Position ) extends Block case class LinkDefinition( id : String, url : String, title : Option[String], position : Position ) extends Block case class Blockquote( children : Seq[Block], position : Position ) extends Block case class CodeBlock( text : Text, position : Position ) extends Block case class HorizontalRule( position : Position ) extends Block case class OrderedItem( children : Seq[Block], position : Position ) extends Block case class UnorderedItem( children : Seq[Block], position : Position ) extends Block case class HTMLBlock( html: String, position: Position ) extends Block case class OrderedList( items : Seq[OrderedItem] ) extends Block { lazy val position = if ( items.isEmpty ) NoPosition else items.head.position } case class UnorderedList( items : Seq[UnorderedItem] ) extends Block { lazy val position = if ( items.isEmpty ) NoPosition else items.head.position }
ãã ãµããã®ã¾ã¾ã§ããã ã¨ãããã¨ã§ãHeader ãäºåã«å ¨ã¦å¼ã£ãæãã¦ãç´¢å¼ãä½ãããã¨æã£ãã
import java.io.PrintWriter import scala.io.{Codec, Source} import com.tristanhunt.knockoff.DefaultDiscounter._ import com.tristanhunt.knockoff._ import scala.util.parsing.input.{NoPosition, Position} object Sample extends App { // ãã¼ã¹ã¨ãªããã¼ã¿ val source = Source.fromFile("sample.txt")(Codec.UTF8) var content = knockoff(source.getLines().mkString("\n")) // Header å®ç¾©ããªã³ã¯ã«å¤æãã var counter = 0 def mkLi(num:Int, h:Header) = { val Header(l, s, p) = h """<li><a href="#%d">%s</a></li>""".format(num, s.head.asInstanceOf[Text].content) } // Header ãæãåºãã¦ããªã³ã¯ã®ãªã¹ãã«å¤æãã val headers = content.filter(_.isInstanceOf[Header]).map(_.asInstanceOf[Header]) .zipWithIndex.map { case (header, num) => mkLi(num + 1, header) } val headerList = HTMLBlock("""<ul>%s</ul>""".format(headers.mkString), NoPosition) // Header å ã®ããã¹ãã« id ãä»ä¸ãã def convertLinkSpan(s:Span) = { s match { case Text(content) => { counter += 1 HTMLSpan("""<span id="%d">%s</span>""".format(counter, content)) } case s => s } } // ãããã« id ãæ¯ã content = content.map(v => { v match { case Header(l, s, p) => Header(l, s.map(convertLinkSpan), p) case v => v } }) val converted = new PrintWriter("output.html") converted.println("<html><body>") // ãªã³ã¯ converted.println(toXHTML(headerList +: content)) converted.println("</body></html>") converted.flush() converted.close() }
ã¦ãªæãã§æ¸ãã¨
<html><body> <ul><li><a href="#1">PlayFramework ãã¤ã³ã¹ãã¼ã«ãã</a></li><li><a href="#2">Playããã¸ã§ã¯ããä½æãã</a></li></ul><h1><span id="1">PlayFramework ãã¤ã³ã¹ãã¼ã«ãã</span></h1><p>Playframework 2.1.1 ãã¤ã³ã¹ãã¼ã«ããæé ã§ã </p><ol><li>Java6 以ä¸ãå ¥ãã¾ã(ãã®è©³ç´°ã¯Javaã®ç©ãæ¢ãã¦ãã ãã) </li><li><a href="http://www.playframework.com/:title">Playå ¬å¼</a>ãã2.1.1 ããã¦ã³ãã¼ããã¦ãã¾ã </li><li>é©å½ãªãã£ã¬ã¯ããªã¸è§£åãããã¹ãéãã¾ã </li></ol><p>åºæ¬çã«ã¯ããã ãã§ãã </p><pre><code>wget http://downloads.typesafe.com/play/2.1.1/play-2.1.1.zip unzip play-2.1.1.zip sudo mv play-2.1.1 /usr/local/ ... (以ä¸ç¥)