emithtml.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 360 行
SCALA
360 行
/* NSC -- new Scala compiler * Copyright 2005-2007 LAMP/EPFL * @author Stephane Micheloud * Adapted from Lex Spoon's sbaz manual *///$Id: EmitHtml.scala 13591 2007-12-19 11:10:01Z odersky $package scala.tools.docutilobject EmitHtml { import scala.xml.{Node, NodeBuffer, NodeSeq, XML} import ManPage._ val out = Console def escape(text: String) = text.replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">")/* */ def emitSection(section: Section, depth: int) { def emitPara(text: AbstractText) { out.println("<div>") emitText(text) out.println("\n</div>") } def emitText(text: AbstractText): Unit = text match { case seq:SeqText => seq.components.foreach(emitText) case seq:SeqPara => seq.components.foreach(emitPara) case Text(text) => out.print(escape(text)) case BSlash => out.print("\\") case MDash => out.print("—") case NDash => out.print("–") case Bold(text) => out.print("<b>") emitText(text) out.print("</b>") case Italic(text) => out.print("<i>") emitText(text) out.print("</i>") case Emph(text) => out.print("<em>") emitText(text) out.print("</em>") case Mono(text) => out.print("<code>") emitText(text) out.print("</code>") case Quote(text) => out.print("\"") emitText(text) out.print("\"") case DefinitionList(definitions @ _*) => out.println("<ins><dl>") for (d <- definitions) { out.println("<dt>") emitText(d.term) out.println("\n</dt>") out.println("<dd>") emitText(d.description) out.println("</dd>") } out.println("</dl></ins>") case Link(label, url) => out.print("<a href=\"" + url + "\">") emitText(label) out.print("</a>") case _ => error("unknown text node: " + text) } def emitParagraph(para: Paragraph): Unit = para match { case TextParagraph(text) => out.println("<p>") emitText(text) out.println("</p>") case BlockQuote(text) => out.println("<blockquote><p>") emitText(text) out.println("</p></blockquote>") case CodeSample(text) => out.print("<pre>") out.print(escape(text)) out.println("</pre>") case lst:BulletList => out.println("<ul>") for (item <- lst.items) { out.print("<li>") emitText(item) out.println("</li>") } out.println("</ul>") case lst:NumberedList => out.println("<ol>") for (item <- lst.items) { out.print("<li>") emitText(item) } out.println("</ol>") case TitledPara(title, text) => out.println("<p><strong>" + escape(title) + "</strong></p>") emitText(text) case EmbeddedSection(sect) => emitSection(sect, depth + 1) case _ => error("unknown paragraph node: " + para) } val name = section.title.replaceAll("\\p{Space}", "_").toLowerCase() out.println("\n<h" + depth + " id=\"" + name + "\">" + section.title + "</h" + depth + ">") section.paragraphs.foreach(emitParagraph) } private def emit3columns(col1: String, col2: String, col3: String) = { out.println("<div style=\"float:left;\">") out.println(col1) out.println("</div>") out.println("<div style=\"float:right;\">") out.println(col3) out.println("</div>") out.println("<div style=\"text-align:center;\">") out.println(col2) out.println("</div>") } private def emitHeader(col1: String, col2: String, col3: String) = { out.println("<!-- header -->") out.println("<div style=\"margin: 0 0 2em 0;\">") emit3columns(col1, col2, col3) out.println("</div>") } private def emitFooter(col1: String, col2: String, col3: String) = { out.println("<!-- footer -->") out.println("<div style=\"margin: 2em 0 0 0;\">") emit3columns(col1, col2, col3) out.println("</div>") } def emitDocument(document: Document) = { out.println("<?xml version=\"1.1\" encoding=\"" + document.encoding + "\"?>") out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">") out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n") out.println("<head>") out.println("<title>" + document.title + " man page</title>") out.println("<meta http-equiv=\"Content-Language\" content=\"en\"/>") out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + document.encoding + "\"/>") out.println("<meta name=\"Author\" content=\"" + document.author + "\"/>") out.println("<style type=\"text/css\">") out.println(" <!--") out.println(" blockquote, pre { margin:1em 4em 1em 4em; }") out.println(" dt { margin: 0.6em 0 0 0; }") out.println(" p { margin:0.6em 2em 0.6em 2em; text-align:justify; }") out.println(" //-->") out.println("</style>") out.println("</head>\n") out.println("<body>") val name = document.title + "(" + document.category.id + ")" emitHeader(name, "" + document.category, name) document.sections.foreach(s => emitSection(s, 3)) emitFooter("version " + document.version, document.date, name) out.println("</body>") out.println("</html>") }/* *//* private def group(ns: Iterable[NodeSeq]): NodeSeq = { val zs = new NodeBuffer for (z <- ns) { zs &+ z } zs } def emitSection(section: Section, depth: int): NodeSeq = { def emitText(text: AbstractText): NodeSeq = text match { case seq:SeqText => group(seq.components.toList.map(item => emitText(item))) case Text(text) => scala.xml.Text(escape(text)) case MDash => scala.xml.Text("—") case NDash => scala.xml.Text("–") case Bold(text) => <b>{emitText(text)}</b> case Italic(text) => <i>{emitText(text)}</i> case Emph(text) => <em>{emitText(text)}</em> case Mono(text) => <code>{emitText(text)}</code> case Quote(text) => emitText("\"" & text & "\"") case DefinitionList(definitions @ _*) => <ins><dl> {definitions.toList.map(d => <dt>{emitText(d.term)}</dt> <dd>{emitText(d.description)}</dd> )} </dl></ins> case Link(label, url) => <a href={url}>{emitText(label)}</a> case _ => error("unknown text node " + text) } def emitParagraph(para: Paragraph): NodeSeq = para match { case TextParagraph(text) => <p>{emitText(text)}</p> case BlockQuote(text) => <blockquote>{emitText(text)}</blockquote> case CodeSample(text) => <blockquote><pre>{escape(text)}</pre></blockquote> case lst:BulletList => <ul> {lst.items.toList.map(item => <li>{emitText(item)}</li>)} </ul> case lst:NumberedList => <ol> {lst.items.toList.map(item => <li>{emitText(item)}</li>)} </ol> case TitledPara(title, text) => <p><strong>{escape(title)}</strong></p> {emitText(text)} case EmbeddedSection(sect) => {emitSection(sect, depth + 1)} case _ => error("unknown paragraph node " + para) } val name = section.title.replaceAll("\\p{Space}", "_").toLowerCase() <h3 id={name}>{section.title}</h3>.concat( group(section.paragraphs.toList.map(p => emitParagraph(p)))) } private def emit3columns(col1: String, col2: String, col3: String): NodeSeq = <div style="float:left;">{col1}</div> <div style="float:right;">{col3}</div> <div style="text-align:center;">{col2}</div> <div style="clear:both;"></div> private def emitHeader(col1: String, col2: String, col3: String): NodeSeq = <div style="margin: 0 0 2em 0;"> {emit3columns(col1, col2, col3)} </div> private def emitFooter(col1: String, col2: String, col3: String): NodeSeq = { scala.xml.Comment("footer") <div style="margin: 2em 0 0 0;"> {emit3columns(col1, col2, col3)} </div> } def emitDocument(document: Document, addDocType: Boolean) = { val name = document.title + "(" + document.category.id + ")" val doc = <html xml:lang="en"> <head> <title>{document.title}</title> <meta http-equiv="Content-Language" content="en"/> <meta http-equiv="Content-Type" content={"text/html; charset=" + document.encoding}/> <meta name="Author" content={document.author}/> <style type="text/css"> {" blockquote, pre { margin:1em 4em 1em 4em; }\n" + " p { margin:1em 2em 1em 2em; text-align:justify; }\n"} </style> </head> <body> {emitHeader(name, "" + document.category, name)} {document.sections.map(s => emitSection(s, 2))} {emitFooter("version " + document.version, document.date, name)} </body> </html> out.println(doc)/* val w = new java.io.StringWriter val id = scala.xml.dtd.PublicID("PUBLIC", null) val dtd = null //scala.xml.dtd.DEFAULT(true, "") val doctype = scala.xml.dtd.DocType("html", id, null) //List(dtd)) XML.write(w, doc, document.encoding, true/ *xmlDecl* /, doctype) out.println(w.toString())*/ }*/ def main(args: Array[String]) { if (args.length < 1) { System.err.println("usage: EmitHtml <classname>") exit(1) } type AnyClass = Class[_] try { val cl = this.getClass.getClassLoader() val clasz = cl.loadClass(args(0)) val meth = clasz.getDeclaredMethod("manpage", Array[AnyClass]()) val doc = meth.invoke(null, Array[Object]()).asInstanceOf[Document] emitDocument(doc) } catch { case ex: Exception => ex.printStackTrace() System.err.println("Error in EmitHtml") exit(1) } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?