{"action":"created","comment":{"url":"https://api.github.com/repos/lift/framework/pulls/comments/22699488","id":22699488,"diff_hunk":"@@ -0,0 +1,102 @@\n+/*\n+ * Copyright 2007-2015 WorldWide Conferencing, LLC\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *     http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package net.liftweb\n+package http\n+\n+import java.io.InputStream\n+\n+import net.liftweb.common.Box\n+import net.liftweb.util.Helpers\n+\n+import scala.xml.NodeSeq\n+\n+/**\n+ * Objects which can parse content should implement this trait. See [[LiftRules.contentParsers]]\n+ */\n+trait ContentParser {\n+  /**\n+   * The template filename suffixes this parser is for, e.g. \"html\", \"md\", \"adoc\", etc.\n+   */\n+  def templateSuffixes: Seq[String]\n+\n+  /**\n+   * Given an InputStream to a resource with a matching suffix, this function should provide the corresponding\n+   * NodeSeq ready to serve\n+   * @return\n+   */\n+  def parse(content:InputStream): Box[NodeSeq]\n+\n+  /**\n+   * Called to auto-surround the content when needed, i.e. when this content is a top-level template\n+   */\n+  def surround(content:NodeSeq): NodeSeq\n+}\n+\n+object ContentParser {\n+  /**\n+   * Convenience function to convert a simple `String => Box[NodeSeq]` content parser function into a\n+   * `InputStream => Box[NodeSeq]` function for satisfying the `ContentParser` contract.\n+   * @param simpleParser your `String => Box[NodeSeq]` content parser\n+   * @return your parser wrapped up to handle an `InputStream`\n+   */\n+  def toInputStreamParser(simpleParser: String=>Box[NodeSeq]): InputStream=>Box[NodeSeq] = {\n+    is:InputStream =>\n+      for {\n+        bytes <- Helpers.tryo(Helpers.readWholeStream(is))\n+        elems <- simpleParser(new String(bytes, \"UTF-8\"))\n+      } yield {\n+        elems\n+      }\n+  }\n+\n+  /**\n+   * Default surround function used by `ContentParser.basic` and the built-it markdown parser which results in the\n+   * template being surrounded by `default.html` with the content located at `id=content`.\n+   */\n+  val defaultSurround: NodeSeq=>NodeSeq =\n+    { elems => <lift:surround with=\"default\" at=\"content\">{elems}</lift:surround> }\n+\n+  /**\n+   * A basic `ContentParser` which handles one template filename suffix, operates on a string, and surrounds the\n+   * top-level templates with the default surround.\n+   * @param templateSuffix the template filename suffix for which this parser will be utilized.\n+   * @param parseFunction the parse function for converting the template as a string into a `NodeSeq`.\n+   * @param surroundFunction the function for surrounding the content returned by the `parseFunction`.\n+   *                         See [[defaultSurround]].\n+   */\n+  def basic(templateSuffix: String,\n+            parseFunction: String=>Box[NodeSeq],\n+            surroundFunction: NodeSeq=>NodeSeq = defaultSurround):ContentParser =\n+    new ContentParser {\n+      override def templateSuffixes: Seq[String] = Seq(templateSuffix)\n+      override def parse(content: InputStream): Box[NodeSeq] = toInputStreamParser(parseFunction)(content)\n+      override def surround(content: NodeSeq): NodeSeq = surroundFunction(content)\n+    }\n+\n+  /**\n+   * A full `ContentParser` which handles multiple filename suffixes, operates on an `InputStream`, and surrounds the\n+   * top-level templates with the default surround\n+   */\n+  def full(templateSuffixesSeq: Seq[String],\n+           parseF: InputStream=>Box[NodeSeq],\n+           surroundF: NodeSeq=>NodeSeq = defaultSurround):ContentParser =","path":"web/webkit/src/main/scala/net/liftweb/http/ContentParser.scala","position":96,"original_position":96,"commit_id":"e42fbed50c00deeebfd2cfc09f91f6ecb51a75a7","original_commit_id":"e42fbed50c00deeebfd2cfc09f91f6ecb51a75a7","user":{"login":"joescii","id":882948,"avatar_url":"https://avatars.githubusercontent.com/u/882948?v=3","gravatar_id":"","url":"https://api.github.com/users/joescii","html_url":"https://github.com/joescii","followers_url":"https://api.github.com/users/joescii/followers","following_url":"https://api.github.com/users/joescii/following{/other_user}","gists_url":"https://api.github.com/users/joescii/gists{/gist_id}","starred_url":"https://api.github.com/users/joescii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joescii/subscriptions","organizations_url":"https://api.github.com/users/joescii/orgs","repos_url":"https://api.github.com/users/joescii/repos","events_url":"https://api.github.com/users/joescii/events{/privacy}","received_events_url":"https://api.github.com/users/joescii/received_events","type":"User","site_admin":false},"body":"Got it! And I like it...","created_at":"2015-01-09T03:06:21Z","updated_at":"2015-01-09T03:06:21Z","html_url":"https://github.com/lift/framework/pull/1652#discussion_r22699488","pull_request_url":"https://api.github.com/repos/lift/framework/pulls/1652","_links":{"self":{"href":"https://api.github.com/repos/lift/framework/pulls/comments/22699488"},"html":{"href":"https://github.com/lift/framework/pull/1652#discussion_r22699488"},"pull_request":{"href":"https://api.github.com/repos/lift/framework/pulls/1652"}}},"pull_request":{"url":"https://api.github.com/repos/lift/framework/pulls/1652","id":26566271,"html_url":"https://github.com/lift/framework/pull/1652","diff_url":"https://github.com/lift/framework/pull/1652.diff","patch_url":"https://github.com/lift/framework/pull/1652.patch","issue_url":"https://api.github.com/repos/lift/framework/issues/1652","number":1652,"state":"open","locked":false,"title":"Unified parsers","user":{"login":"joescii","id":882948,"avatar_url":"https://avatars.githubusercontent.com/u/882948?v=3","gravatar_id":"","url":"https://api.github.com/users/joescii","html_url":"https://github.com/joescii","followers_url":"https://api.github.com/users/joescii/followers","following_url":"https://api.github.com/users/joescii/following{/other_user}","gists_url":"https://api.github.com/users/joescii/gists{/gist_id}","starred_url":"https://api.github.com/users/joescii/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joescii/subscriptions","organizations_url":"https://api.github.com/users/joescii/orgs","repos_url":"https://api.github.com/users/joescii/repos","events_url":"https://api.github.com/users/joescii/events{/privacy}","received_events_url":"https://api.github.com/users/joescii/received_events","type":"User","site_admin":false},"body":"Enhancement for configuring parsers per [this thread](https://groups.google.com/forum/#!topic/liftweb/WnaUFd9Fw5E).","created_at":"2014-12-24T18:29:54Z","updated_at":"2015-01-09T03:06:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"22aa741edec0400cff51f9707411e871f2bce2c0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/lift/framework/pulls/1652/commits","review_comments_url":"https://api.github.com/repos/lift/framework/pulls/1652/comments","review_comment_url":"https://api.github.com/repos/lift/framework/pulls/comments/{number}","comments_url":"https://api.github.com/repos/lift/framework/issues/1652/comments","statuses_url":"https://api.github.com/repos/lift/framework/statuses/e42fbed50c00deeebfd2cfc09f91f6ecb51a75a7","head":{"label":"lift:unified-parsers","ref":"unified-parsers","sha":"e42fbed50c00deeebfd2cfc09f91f6ecb51a75a7","user":{"login":"lift","id":317975,"avatar_url":"https://avatars.githubusercontent.com/u/317975?v=3","gravatar_id":"","url":"https://api.github.com/users/lift","html_url":"https://github.com/lift","followers_url":"https://api.github.com/users/lift/followers","following_url":"https://api.github.com/users/lift/following{/other_user}","gists_url":"https://api.github.com/users/lift/gists{/gist_id}","starred_url":"https://api.github.com/users/lift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lift/subscriptions","organizations_url":"https://api.github.com/users/lift/orgs","repos_url":"https://api.github.com/users/lift/repos","events_url":"https://api.github.com/users/lift/events{/privacy}","received_events_url":"https://api.github.com/users/lift/received_events","type":"Organization","site_admin":false},"repo":{"id":1295197,"name":"framework","full_name":"lift/framework","owner":{"login":"lift","id":317975,"avatar_url":"https://avatars.githubusercontent.com/u/317975?v=3","gravatar_id":"","url":"https://api.github.com/users/lift","html_url":"https://github.com/lift","followers_url":"https://api.github.com/users/lift/followers","following_url":"https://api.github.com/users/lift/following{/other_user}","gists_url":"https://api.github.com/users/lift/gists{/gist_id}","starred_url":"https://api.github.com/users/lift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lift/subscriptions","organizations_url":"https://api.github.com/users/lift/orgs","repos_url":"https://api.github.com/users/lift/repos","events_url":"https://api.github.com/users/lift/events{/privacy}","received_events_url":"https://api.github.com/users/lift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/lift/framework","description":"Lift Framework","fork":false,"url":"https://api.github.com/repos/lift/framework","forks_url":"https://api.github.com/repos/lift/framework/forks","keys_url":"https://api.github.com/repos/lift/framework/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lift/framework/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lift/framework/teams","hooks_url":"https://api.github.com/repos/lift/framework/hooks","issue_events_url":"https://api.github.com/repos/lift/framework/issues/events{/number}","events_url":"https://api.github.com/repos/lift/framework/events","assignees_url":"https://api.github.com/repos/lift/framework/assignees{/user}","branches_url":"https://api.github.com/repos/lift/framework/branches{/branch}","tags_url":"https://api.github.com/repos/lift/framework/tags","blobs_url":"https://api.github.com/repos/lift/framework/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lift/framework/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lift/framework/git/refs{/sha}","trees_url":"https://api.github.com/repos/lift/framework/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lift/framework/statuses/{sha}","languages_url":"https://api.github.com/repos/lift/framework/languages","stargazers_url":"https://api.github.com/repos/lift/framework/stargazers","contributors_url":"https://api.github.com/repos/lift/framework/contributors","subscribers_url":"https://api.github.com/repos/lift/framework/subscribers","subscription_url":"https://api.github.com/repos/lift/framework/subscription","commits_url":"https://api.github.com/repos/lift/framework/commits{/sha}","git_commits_url":"https://api.github.com/repos/lift/framework/git/commits{/sha}","comments_url":"https://api.github.com/repos/lift/framework/comments{/number}","issue_comment_url":"https://api.github.com/repos/lift/framework/issues/comments/{number}","contents_url":"https://api.github.com/repos/lift/framework/contents/{+path}","compare_url":"https://api.github.com/repos/lift/framework/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lift/framework/merges","archive_url":"https://api.github.com/repos/lift/framework/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lift/framework/downloads","issues_url":"https://api.github.com/repos/lift/framework/issues{/number}","pulls_url":"https://api.github.com/repos/lift/framework/pulls{/number}","milestones_url":"https://api.github.com/repos/lift/framework/milestones{/number}","notifications_url":"https://api.github.com/repos/lift/framework/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lift/framework/labels{/name}","releases_url":"https://api.github.com/repos/lift/framework/releases{/id}","created_at":"2011-01-26T13:25:28Z","updated_at":"2015-01-08T12:29:58Z","pushed_at":"2015-01-08T04:14:16Z","git_url":"git://github.com/lift/framework.git","ssh_url":"git@github.com:lift/framework.git","clone_url":"https://github.com/lift/framework.git","svn_url":"https://github.com/lift/framework","homepage":"http://liftweb.net","size":29151,"stargazers_count":840,"watchers_count":840,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":204,"mirror_url":null,"open_issues_count":140,"forks":204,"open_issues":140,"watchers":840,"default_branch":"master"}},"base":{"label":"lift:master","ref":"master","sha":"efc7976c8d78170d5fb06f6216b425bacf76509c","user":{"login":"lift","id":317975,"avatar_url":"https://avatars.githubusercontent.com/u/317975?v=3","gravatar_id":"","url":"https://api.github.com/users/lift","html_url":"https://github.com/lift","followers_url":"https://api.github.com/users/lift/followers","following_url":"https://api.github.com/users/lift/following{/other_user}","gists_url":"https://api.github.com/users/lift/gists{/gist_id}","starred_url":"https://api.github.com/users/lift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lift/subscriptions","organizations_url":"https://api.github.com/users/lift/orgs","repos_url":"https://api.github.com/users/lift/repos","events_url":"https://api.github.com/users/lift/events{/privacy}","received_events_url":"https://api.github.com/users/lift/received_events","type":"Organization","site_admin":false},"repo":{"id":1295197,"name":"framework","full_name":"lift/framework","owner":{"login":"lift","id":317975,"avatar_url":"https://avatars.githubusercontent.com/u/317975?v=3","gravatar_id":"","url":"https://api.github.com/users/lift","html_url":"https://github.com/lift","followers_url":"https://api.github.com/users/lift/followers","following_url":"https://api.github.com/users/lift/following{/other_user}","gists_url":"https://api.github.com/users/lift/gists{/gist_id}","starred_url":"https://api.github.com/users/lift/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lift/subscriptions","organizations_url":"https://api.github.com/users/lift/orgs","repos_url":"https://api.github.com/users/lift/repos","events_url":"https://api.github.com/users/lift/events{/privacy}","received_events_url":"https://api.github.com/users/lift/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/lift/framework","description":"Lift Framework","fork":false,"url":"https://api.github.com/repos/lift/framework","forks_url":"https://api.github.com/repos/lift/framework/forks","keys_url":"https://api.github.com/repos/lift/framework/keys{/key_id}","collaborators_url":"https://api.github.com/repos/lift/framework/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/lift/framework/teams","hooks_url":"https://api.github.com/repos/lift/framework/hooks","issue_events_url":"https://api.github.com/repos/lift/framework/issues/events{/number}","events_url":"https://api.github.com/repos/lift/framework/events","assignees_url":"https://api.github.com/repos/lift/framework/assignees{/user}","branches_url":"https://api.github.com/repos/lift/framework/branches{/branch}","tags_url":"https://api.github.com/repos/lift/framework/tags","blobs_url":"https://api.github.com/repos/lift/framework/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/lift/framework/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/lift/framework/git/refs{/sha}","trees_url":"https://api.github.com/repos/lift/framework/git/trees{/sha}","statuses_url":"https://api.github.com/repos/lift/framework/statuses/{sha}","languages_url":"https://api.github.com/repos/lift/framework/languages","stargazers_url":"https://api.github.com/repos/lift/framework/stargazers","contributors_url":"https://api.github.com/repos/lift/framework/contributors","subscribers_url":"https://api.github.com/repos/lift/framework/subscribers","subscription_url":"https://api.github.com/repos/lift/framework/subscription","commits_url":"https://api.github.com/repos/lift/framework/commits{/sha}","git_commits_url":"https://api.github.com/repos/lift/framework/git/commits{/sha}","comments_url":"https://api.github.com/repos/lift/framework/comments{/number}","issue_comment_url":"https://api.github.com/repos/lift/framework/issues/comments/{number}","contents_url":"https://api.github.com/repos/lift/framework/contents/{+path}","compare_url":"https://api.github.com/repos/lift/framework/compare/{base}...{head}","merges_url":"https://api.github.com/repos/lift/framework/merges","archive_url":"https://api.github.com/repos/lift/framework/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/lift/framework/downloads","issues_url":"https://api.github.com/repos/lift/framework/issues{/number}","pulls_url":"https://api.github.com/repos/lift/framework/pulls{/number}","milestones_url":"https://api.github.com/repos/lift/framework/milestones{/number}","notifications_url":"https://api.github.com/repos/lift/framework/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/lift/framework/labels{/name}","releases_url":"https://api.github.com/repos/lift/framework/releases{/id}","created_at":"2011-01-26T13:25:28Z","updated_at":"2015-01-08T12:29:58Z","pushed_at":"2015-01-08T04:14:16Z","git_url":"git://github.com/lift/framework.git","ssh_url":"git@github.com:lift/framework.git","clone_url":"https://github.com/lift/framework.git","svn_url":"https://github.com/lift/framework","homepage":"http://liftweb.net","size":29151,"stargazers_count":840,"watchers_count":840,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":204,"mirror_url":null,"open_issues_count":140,"forks":204,"open_issues":140,"watchers":840,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/lift/framework/pulls/1652"},"html":{"href":"https://github.com/lift/framework/pull/1652"},"issue":{"href":"https://api.github.com/repos/lift/framework/issues/1652"},"comments":{"href":"https://api.github.com/repos/lift/framework/issues/1652/comments"},"review_comments":{"href":"https://api.github.com/repos/lift/framework/pulls/1652/comments"},"review_comment":{"href":"https://api.github.com/repos/lift/framework/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/lift/framework/pulls/1652/commits"},"statuses":{"href":"https://api.github.com/repos/lift/framework/statuses/e42fbed50c00deeebfd2cfc09f91f6ecb51a75a7"}}}}