BlackQuill
| Revision | 1d0196cbbf367c9aefe501108615d7be23f7895c (tree) |
|---|---|
| Time | 2013-05-27 00:25:12 |
| Author | |
| Commiter | Set |
implement list feature
| @@ -11,13 +11,46 @@ bbbbb<-testccccccc | ||
| 11 | 11 | コメント |
| 12 | 12 | --> |
| 13 | 13 | *AAA* |
| 14 | -* abc | |
| 15 | - * ABC | |
| 16 | - * DE | |
| 17 | -* def | |
| 18 | - * ABC | |
| 19 | - * CDE | |
| 20 | -* ghi | |
| 14 | + * abc | |
| 15 | + * ABC | |
| 16 | + * DEFFF | |
| 17 | + * def | |
| 18 | + * ABCCC | |
| 19 | + * CDE | |
| 20 | + * ghi | |
| 21 | + | |
| 22 | + - A | |
| 23 | + - B | |
| 24 | + - C | |
| 25 | + - D | |
| 26 | + | |
| 27 | + + AA | |
| 28 | + + BB | |
| 29 | + + CC | |
| 30 | + + DD | |
| 31 | + | |
| 32 | + * AAA | |
| 33 | + + BBB | |
| 34 | + + CCC | |
| 35 | + - DDD | |
| 36 | + - EEE | |
| 37 | + | |
| 38 | + * A | |
| 39 | + * B | |
| 40 | + * C | |
| 41 | + * D | |
| 42 | + * E | |
| 43 | + * F | |
| 44 | + * G | |
| 45 | + | |
| 46 | + | |
| 47 | + 1. A | |
| 48 | + 2. B | |
| 49 | + 3. C | |
| 50 | + 4. D | |
| 51 | + 5. E | |
| 52 | + 6. F | |
| 53 | + 7. G | |
| 21 | 54 | |
| 22 | 55 | <h1>aaaaa</h1> |
| 23 | 56 | あああ |
| \ No newline at end of file |
| @@ -7,6 +7,9 @@ package org.blackquill.engine | ||
| 7 | 7 | import org.apache.commons.logging._ |
| 8 | 8 | import scala.collection.immutable.List |
| 9 | 9 | import scala.collection.mutable.LinkedHashMap |
| 10 | +import scala.collection.mutable.Stack | |
| 11 | +import scala.collection.mutable.ListMap | |
| 12 | +import scala.collection.SortedSet | |
| 10 | 13 | import scala.util.matching.Regex |
| 11 | 14 | import scala.xml._ |
| 12 | 15 |
| @@ -16,97 +19,121 @@ class BQParser { | ||
| 16 | 19 | private val log:Log = LogFactory.getLog(classOf[BQParser]) |
| 17 | 20 | |
| 18 | 21 | private val Syntax = LinkedHashMap( |
| 19 | - "^(.*?)((\\s*\\*\\s.+?\\\\,)+)(.*?)$$" -> ("ul",surroundByListTAG _), | |
| 20 | - "^(.*?)\\*(.+?)\\*(.*?)$$" -> ("i",surroundByAbstructTAG _), | |
| 21 | - "^(.*?)\\*\\*(.+?)\\*\\*(.*?)$$" -> ("em",surroundByAbstructTAG _), | |
| 22 | + "^(.*?)((\\s+\\d+?\\.\\s.+?\\\\,\\s*?)+)\\\\,\\s*?(.*?)$$" -> ("ol",surroundByListTAG _), | |
| 23 | + "^(.*?)((\\s+[\\*|\\+|\\-]\\s.+?\\\\,\\s*?)+)\\\\,\\s*?(.*?)$$" -> ("ul",surroundByListTAG _), | |
| 24 | + "^(.*?)\\*(.+?)\\*(.*?)$$" -> ("i",surroundByGeneralTAG _), | |
| 25 | + "^(.*?)\\*\\*(.+?)\\*\\*(.*?)$$" -> ("em",surroundByGeneralTAG _), | |
| 22 | 26 | "^(.*?)(#+)\\s(.+?)\\\\,(.*?)$$" -> ("h",surroundByHeadTAG _) |
| 23 | 27 | //"^(.*?)(\\\\,.+?\\\\,)(.*?)$$" -> ("p",surroundByAbstructTAG _) |
| 24 | 28 | ) |
| 25 | 29 | |
| 26 | -/* | |
| 27 | - private def controlStyle(style:List[String]):String = { | |
| 28 | - if(style.size == 0){ | |
| 29 | - log warn "<ul> style: too many nests found where listed by by *" | |
| 30 | - System.exit(-1) | |
| 31 | - return "" | |
| 32 | - }else{return style.head} | |
| 30 | +/* private def ulStyles(index:Int):String = { | |
| 31 | + | |
| 32 | + } | |
| 33 | + | |
| 34 | + private def olStyles(index:Int):String = | |
| 33 | 35 | } |
| 34 | 36 | */ |
| 35 | 37 | private def surroundByListTAG(doc:String, regex:String, TAG:String):String = { |
| 36 | - var styles = List[String]() | |
| 38 | + val p = new Regex(regex, "before","elements","element","following") | |
| 39 | + val m = p findFirstMatchIn(doc) | |
| 40 | + var s = "" | |
| 41 | + var bef = "" | |
| 42 | + var fol = "" | |
| 43 | + | |
| 44 | + if(m != None){ | |
| 45 | + if(m.get.group("before") != None){bef = m.get.group("before")}else{bef = ""} | |
| 46 | + if(m.get.group("following") != None){fol = m.get.group("following")}else{fol = ""} | |
| 47 | + s = m.get.group("elements") | |
| 48 | + }else{ | |
| 49 | + return doc | |
| 50 | + } | |
| 51 | + | |
| 52 | + | |
| 37 | 53 | var sign = "" |
| 38 | 54 | var sp = "" |
| 39 | - val ulStyles = List[String]("disc","disc","disc","circle","circle","circle","square","square","square") | |
| 40 | - val olStyles = List[String]("disc","circle","square") | |
| 55 | + val indentWidth = 4 | |
| 56 | + var styles:((Int) => String) = null | |
| 57 | + | |
| 41 | 58 | TAG match{ |
| 42 | 59 | case "ul"=> |
| 43 | 60 | sp = TAG |
| 44 | - styles = ulStyles | |
| 45 | - sign = "*" | |
| 61 | + styles = (index:Int) => { | |
| 62 | + (index/indentWidth)%3 match{ | |
| 63 | + case 1 => "disc" | |
| 64 | + case 2 => "circle" | |
| 65 | + case 0 => "square" | |
| 66 | + case _ => "---" | |
| 67 | + } | |
| 68 | + } | |
| 69 | + sign = "[\\*|\\+|\\-]" | |
| 46 | 70 | case "ol"=> |
| 47 | 71 | sp = TAG |
| 48 | - styles = olStyles | |
| 49 | - sign = "-" | |
| 72 | + styles = (index:Int) => { | |
| 73 | + (index/indentWidth)%4 match{ | |
| 74 | + case 1 => "decimal" | |
| 75 | + case 2 => "decimal-leading-zero" | |
| 76 | + case 3 => "upper-latin" | |
| 77 | + case 0 => "lower-latin" | |
| 78 | + case _ => "---" | |
| 79 | + } | |
| 80 | + } | |
| 81 | + sign = "\\d+?\\." | |
| 50 | 82 | } |
| 51 | - var tree = new TreeNode[String]("root") | |
| 83 | + | |
| 84 | + var docList = List[String]() | |
| 85 | + for(elem <- s"""(\\s+?$sign\\s.+?\\\\,)+?""".r.findAllMatchIn(s)){ | |
| 86 | + docList = elem.group(1)::docList | |
| 87 | + } | |
| 88 | + | |
| 52 | 89 | |
| 53 | - def _surroundByListTAG(doc:String, regex:String, TAG:String, style:List[String],indent:Int):String = { | |
| 54 | - if(doc == ""){return ""} | |
| 55 | - if(style.size == 0){ | |
| 56 | - log warn s"<$sp> style: too many nests or wrong notation found where listing by $sp" | |
| 57 | - System.exit(-1) | |
| 58 | - return "" | |
| 59 | - } | |
| 60 | 90 | |
| 61 | - val p = new Regex(regex, "before","elements","element","following") | |
| 62 | - val m = p findFirstMatchIn(doc) | |
| 63 | - if(m != None){ | |
| 64 | - var bef = "" | |
| 65 | - var fol = "" | |
| 91 | + def _surroundByListTAG(doc:List[String],TAG:String,indent:Int):TreeNode[String] = { | |
| 92 | + var tree = new TreeNode[String]("") | |
| 93 | + if(doc.isEmpty){return tree} | |
| 94 | + | |
| 95 | + tree.add(new TreeNode("<" + sp + s""" style=\"list-style-type:${styles(indent)}\">""")) | |
| 96 | + var i = indent | |
| 97 | + var list = List.empty[Tuple3[String,Int,String]] | |
| 98 | + for(elem <- doc){ | |
| 99 | + val m = s"""((\\s+?)$sign\\s(.+?)\\\\,)""".r.findFirstMatchIn(elem) | |
| 100 | + list = (m.get.group(1),m.get.group(2).size,m.get.group(3))::list | |
| 101 | + } | |
| 66 | 102 | |
| 67 | - if(m.get.group("before") != None){bef = m.get.group("before")}else{bef = ""} | |
| 68 | - if(m.get.group("following") != None){fol = m.get.group("following")}else{fol = ""} | |
| 69 | - val s = m.get.group("elements") | |
| 70 | - log info s | |
| 71 | - | |
| 72 | - var str = "" | |
| 73 | - var i = indent | |
| 74 | - var list = List.empty[Tuple3[String,Int,String]] | |
| 75 | - for(elem <- s"""((\\s*?)\\$sign\\s(.+?)\\\\,)+?""".r.findAllMatchIn(s)){ | |
| 76 | - list = (elem.group(1),elem.group(2).size,elem.group(3))::list | |
| 77 | - } | |
| 78 | - var indents = 0 | |
| 79 | - for(elem <- list.reverse){ | |
| 80 | - if(elem._2 != indents){indents = elem._2} | |
| 81 | - if(indents == i){ | |
| 82 | - log info elem._1 + ":" + indents + ":" + elem._3 | |
| 83 | - str += s"<$TAG>" + elem._3 + s"</$TAG>\\," | |
| 84 | - log info "^^^" + elem._1 | |
| 85 | - tree.add(new TreeNode[String](str)) | |
| 86 | - //_surroundByUlListTAG(elem.group("following"),regex,TAG,style.tail,i) | |
| 87 | - }else if(indents > i){ | |
| 88 | - str += _surroundByListTAG(elem._1,regex,TAG,style.tail,indents) | |
| 89 | - log info "%%%" + str | |
| 90 | - tree.add(new TreeNode[String](str)) | |
| 91 | - }else if(indents < i){ | |
| 92 | - str += _surroundByListTAG(elem._1,regex,TAG,style,indents) | |
| 93 | - log info "&&&" + str | |
| 94 | - tree.add(new TreeNode[String](str)) | |
| 95 | - } | |
| 96 | - i = indents | |
| 103 | + var restStr = List[String]() | |
| 104 | + if(list.isEmpty){return new TreeNode("") | |
| 105 | + }else{for(e <- list.reverse.tail){restStr = e._1::restStr}} | |
| 106 | + | |
| 107 | + restStr = restStr.reverse | |
| 108 | + for(elem <- list.reverse){ | |
| 109 | + if(elem._2 > i){ | |
| 110 | + tree.add(new TreeNode("<" + sp + s""" style=\"list-style-type:${styles(elem._2)}\">""")) | |
| 111 | + }else if(elem._2 < i){ | |
| 112 | + tree.add(new TreeNode[String](s"</$sp>"*((i - elem._2)/indentWidth))) | |
| 97 | 113 | } |
| 114 | + tree.add(new TreeNode[String](s"<$TAG>" + elem._3 + s"</$TAG>\\,")) | |
| 98 | 115 | |
| 99 | - val ST:String = style.head | |
| 100 | - log info "---->" | |
| 101 | - for(node <- tree) log info node | |
| 102 | - return _surroundByListTAG(bef,regex,TAG,style,0) + | |
| 103 | - s"""<$sp style=\"list-style-type:$ST\">""" + str + s"""</$sp>\\,""" + | |
| 104 | - _surroundByListTAG(fol,regex,TAG,style,0) | |
| 105 | - | |
| 116 | + | |
| 117 | + if(restStr.isEmpty){ | |
| 118 | + restStr = List[String]("") | |
| 119 | + }else{ | |
| 120 | + restStr = restStr.tail | |
| 121 | + } | |
| 122 | + i = elem._2 | |
| 106 | 123 | } |
| 107 | - doc | |
| 108 | - } | |
| 109 | - _surroundByListTAG(doc,regex,"li",styles,0) | |
| 124 | + tree.add(new TreeNode(s"</$sp>"*((i - indent)/indentWidth + 1))) | |
| 125 | + return tree | |
| 126 | + } | |
| 127 | + val r = s"""^(\\s*)${sign}.*?$$""".r("firstSpace") | |
| 128 | + val wS = r.findFirstMatchIn(s) | |
| 129 | + var str = "" | |
| 130 | + | |
| 131 | + if(wS != None){ | |
| 132 | + for(e <- _surroundByListTAG(docList.reverse,"li",wS.get.group("firstSpace").size)){ | |
| 133 | + str += e.toString() | |
| 134 | + } | |
| 135 | + surroundByListTAG(bef,regex,TAG) + str + surroundByListTAG(fol,regex,TAG) | |
| 136 | + }else{doc} | |
| 110 | 137 | } |
| 111 | 138 | |
| 112 | 139 | private def surroundByHeadTAG(doc:String, regex:String, TAG:String):String = { |
| @@ -130,7 +157,7 @@ class BQParser { | ||
| 130 | 157 | doc |
| 131 | 158 | } |
| 132 | 159 | |
| 133 | - private def surroundByAbstructTAG(doc:String, regex:String, TAG:String):String = { | |
| 160 | + private def surroundByGeneralTAG(doc:String, regex:String, TAG:String):String = { | |
| 134 | 161 | if(doc == ""){return doc} |
| 135 | 162 | log debug doc |
| 136 | 163 | val p = new Regex(regex,"before","inTAG","following") |
| @@ -140,9 +167,9 @@ class BQParser { | ||
| 140 | 167 | var fol = "" |
| 141 | 168 | if(m.get.group("before") != None){bef = m.get.group("before")}else{bef = ""} |
| 142 | 169 | if(m.get.group("following") != None){fol = m.get.group("following")}else{fol = ""} |
| 143 | - return surroundByAbstructTAG(bef,regex,TAG) + | |
| 170 | + return surroundByGeneralTAG(bef,regex,TAG) + | |
| 144 | 171 | s"<${TAG}>" + m.get.group("inTAG") + s"</${TAG}>" + |
| 145 | - surroundByAbstructTAG(fol,regex,TAG) | |
| 172 | + surroundByGeneralTAG(fol,regex,TAG) | |
| 146 | 173 | } |
| 147 | 174 | doc |
| 148 | 175 | } |
| @@ -1,19 +1,29 @@ | ||
| 1 | 1 | package org.blackquill.engine |
| 2 | 2 | |
| 3 | 3 | import scala.collection.immutable.Traversable |
| 4 | +import scala.collection.immutable.List | |
| 4 | 5 | import scala.collection.mutable.ArrayBuffer |
| 5 | 6 | |
| 6 | 7 | class TreeNode[T](val content:T) extends Traversable[T] { |
| 7 | - override def toString="<Node %s>".format(content.toString) | |
| 8 | + override def toString="%s".format(content.toString) | |
| 8 | 9 | |
| 9 | 10 | var parent :Option[TreeNode[T]]=None |
| 10 | - val children=ArrayBuffer[TreeNode[T]]() | |
| 11 | + val children = ArrayBuffer[TreeNode[T]]() | |
| 11 | 12 | |
| 12 | 13 | def add(child :TreeNode[T])={ |
| 13 | 14 | child.parent=Some(this) |
| 14 | 15 | children.append(child) |
| 15 | 16 | child |
| 16 | 17 | } |
| 18 | + | |
| 19 | + def getContents():T = { | |
| 20 | + return content | |
| 21 | + } | |
| 22 | + | |
| 23 | + def getChildren:List[TreeNode[T]] = { | |
| 24 | + val childrenList = children.toList | |
| 25 | + childrenList | |
| 26 | + } | |
| 17 | 27 | |
| 18 | 28 | def foreach[U](f: T => U){ |
| 19 | 29 | for(child <- children){ |
| @@ -21,4 +31,9 @@ class TreeNode[T](val content:T) extends Traversable[T] { | ||
| 21 | 31 | child.foreach(f) |
| 22 | 32 | } |
| 23 | 33 | } |
| 34 | + | |
| 35 | + override def mkString(sep:String):String = { | |
| 36 | + children.mkString(sep) | |
| 37 | + } | |
| 38 | + | |
| 24 | 39 | } |
| \ No newline at end of file |
| @@ -122,9 +122,10 @@ object BlackQuill{ | ||
| 122 | 122 | |
| 123 | 123 | def blackquill(lines:List[String]):List[String] = { |
| 124 | 124 | val str = new HTMLMap htmlTAGFilter lines.mkString("\\,") |
| 125 | + log info str | |
| 125 | 126 | val parsed = new BQParser |
| 126 | 127 | log info parsed.toHTML(str) |
| 127 | - str split """\\,""" toList | |
| 128 | + str split """\\,""" toList | |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | 131 | } |