Last active
August 19, 2016 10:46
-
-
Save jasonqu/56a6a17a74235e2ac70030e0323b27d7 to your computer and use it in GitHub Desktop.
格式化markdown表格
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
exec scala "$0" "$@" | |
!# | |
/** | |
* 目标:格式化md table 表格语法 http://www.tablesgenerator.com/markdown_tables | |
* 注意点:文件的编码 涉及到字符串长度的计算 | |
*/ | |
if (args.length < 1 || args.length > 2) { | |
println( | |
"""Usage: scala NormaMdTable.scala inputMdFile [outputMdFile] | |
| * inputMdFile: the path of the inputFile, eg. a.md | |
| * inputMdFile: the path of the outputFile, if not specified will add a ".md" postfix | |
""".stripMargin) | |
} else { | |
process(args(0), if (args.length == 2) args(1) else args(0) + ".md") | |
} | |
def process(in: String, out: String) = { | |
val source = recurProcess( | |
scala.io.Source.fromFile(args(0), "utf-8").getLines(), List[String]()).reverse | |
import java.io._ | |
val pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(out), "UTF-8")) | |
pw.write(source.mkString("\n")) | |
pw.close() | |
println(s"generate new file in $out") | |
} | |
def recurProcess(source: Iterator[String], content: List[String]): List[String] = { | |
if (!source.hasNext) content | |
else { | |
val line = source.next() | |
if (line.startsWith("|")) { | |
val (tableRest, rest) = source.span(_.startsWith("|")) | |
recurProcess(rest, beautifyMdTable(line +: tableRest.toSeq) :: content) | |
} else { | |
recurProcess(source, line :: content) | |
} | |
} | |
} | |
def beautifyMdTable(table: Seq[String]): String = { | |
def extractContent(table: Seq[String]): Seq[Array[String]] = | |
(table.head +: table.drop(2)).foldRight(Seq[Array[String]]()) { (line, contents) => | |
line.substring(1).split("\\|").map(_.trim) +: contents | |
} | |
def calcDisplayLength(x : String) = { | |
// http://stackoverflow.com/questions/28761385/single-chinese-character-determined-as-length-2-in-java-scala-string useless? | |
// http://zhidao.baidu.com/question/271624295.html | |
//x.length + x.count(c => Character.isIdeographic(c) || (c >= 12288 && c <= 12330) || c > 65248) | |
x.length * 2 - x.count(_.toInt < 1000) | |
} | |
val contents = extractContent(table) | |
// 要考虑中文字符 | |
val beforetrans = contents.map(_.length) | |
if(!beforetrans.forall(_ == beforetrans.head)) | |
println(s"processing $beforetrans with ${contents.map(_.toList)}") | |
val maxlengths: Array[Int] = contents.map(_.map(calcDisplayLength)).transpose.map(_.max + 2).toArray | |
def getTableMd(line: Array[String]): String = { | |
val beautified = for (i <- line.indices) | |
yield " " + line(i) + " " * (maxlengths(i) - calcDisplayLength(line(i)) - 1) | |
beautified.mkString("|", "|", "|") | |
} | |
def second = maxlengths.map("-" * _).mkString("|", "|", "|") | |
(getTableMd(contents.head) +: second +: contents.tail.map(getTableMd)).mkString("\n") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment