From 0055101e4527d0b168f3b147680a678eabca8c50 Mon Sep 17 00:00:00 2001
From: Timothy Gu <timothygu99@gmail.com>
Date: Sat, 16 Apr 2016 18:23:11 -0700
Subject: [PATCH] [mbox mode] Add

---
 doc/compress.html    |   1 +
 mode/index.html      |   1 +
 mode/mbox/index.html |  44 +++++++++++++++
 mode/mbox/mbox.js    | 129 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 175 insertions(+)
 create mode 100644 mode/mbox/index.html
 create mode 100644 mode/mbox/mbox.js

diff --git a/doc/compress.html b/doc/compress.html
index 44e6fea82..4459f46ed 100644
--- a/doc/compress.html
+++ b/doc/compress.html
@@ -168,6 +168,7 @@
           <option value="http://codemirror.net/mode/lua/lua.js">lua.js</option>
           <option value="http://codemirror.net/mode/markdown/markdown.js">markdown.js</option>
           <option value="http://codemirror.net/mode/mathematica/mathematica.js">mathematica.js</option>
+          <option value="http://codemirror.net/mode/mbox/mbox.js">mbox.js</option>
           <option value="http://codemirror.net/mode/mirc/mirc.js">mirc.js</option>
           <option value="http://codemirror.net/mode/mllike/mllike.js">mllike.js</option>
           <option value="http://codemirror.net/mode/modelica/modelica.js">modelica.js</option>
diff --git a/mode/index.html b/mode/index.html
index be583159e..732e0e52c 100644
--- a/mode/index.html
+++ b/mode/index.html
@@ -86,6 +86,7 @@ option.</p>
       <li><a href="lua/index.html">Lua</a></li>
       <li><a href="markdown/index.html">Markdown</a> (<a href="gfm/index.html">GitHub-flavour</a>)</li>
       <li><a href="mathematica/index.html">Mathematica</a></li>
+      <li><a href="mbox/index.html">mbox</a></li>
       <li><a href="mirc/index.html">mIRC</a></li>
       <li><a href="modelica/index.html">Modelica</a></li>
       <li><a href="mscgen/index.html">MscGen</a></li>
diff --git a/mode/mbox/index.html b/mode/mbox/index.html
new file mode 100644
index 000000000..248ea98e1
--- /dev/null
+++ b/mode/mbox/index.html
@@ -0,0 +1,44 @@
+<!doctype html>
+
+<title>CodeMirror: mbox mode</title>
+<meta charset="utf-8"/>
+<link rel=stylesheet href="../../doc/docs.css">
+
+<link rel="stylesheet" href="../../lib/codemirror.css">
+<script src="../../lib/codemirror.js"></script>
+<script src="mbox.js"></script>
+<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
+<div id=nav>
+  <a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
+
+  <ul>
+    <li><a href="../../index.html">Home</a>
+    <li><a href="../../doc/manual.html">Manual</a>
+    <li><a href="https://github.com/codemirror/codemirror">Code</a>
+  </ul>
+  <ul>
+    <li><a href="../index.html">Language modes</a>
+    <li><a class=active href="#">mbox</a>
+  </ul>
+</div>
+
+<article>
+<h2>mbox mode</h2>
+<form><textarea id="code" name="code">
+From timothygu99@gmail.com Sun Apr 17 01:40:43 2016
+From: Timothy Gu &lt;timothygu99@gmail.com&gt;
+Date: Sat, 16 Apr 2016 18:40:43 -0700
+Subject: mbox mode
+Message-ID: &lt;Z8d+bTT50U/az94FZnyPkDjZmW0=@gmail.com&gt;
+
+mbox mode is working!
+
+Timothy
+</textarea></form>
+    <script>
+      var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
+    </script>
+
+    <p><strong>MIME types defined:</strong> <code>application/mbox</code>.</p>
+
+  </article>
diff --git a/mode/mbox/mbox.js b/mode/mbox/mbox.js
new file mode 100644
index 000000000..ba2416ac8
--- /dev/null
+++ b/mode/mbox/mbox.js
@@ -0,0 +1,129 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+var rfc2822 = [
+  "From", "Sender", "Reply-To", "To", "Cc", "Bcc", "Message-ID",
+  "In-Reply-To", "References", "Resent-From", "Resent-Sender", "Resent-To",
+  "Resent-Cc", "Resent-Bcc", "Resent-Message-ID", "Return-Path", "Received"
+];
+var rfc2822NoEmail = [
+  "Date", "Subject", "Comments", "Keywords", "Resent-Date"
+];
+
+CodeMirror.registerHelper("hintWords", "mbox", rfc2822.concat(rfc2822NoEmail));
+
+var whitespace = /^[ \t]/;
+var separator = /^From /; // See RFC 4155
+var rfc2822Header = new RegExp("^(" + rfc2822.join("|") + "): ");
+var rfc2822HeaderNoEmail = new RegExp("^(" + rfc2822NoEmail.join("|") + "): ");
+var header = /^[^:]+:/; // Optional fields defined in RFC 2822
+var email = /^[^ ]+@[^ ]+/;
+var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/;
+var bracketedEmail = /^<.*?>/;
+var untilBracketedEmail = /^.*?(?=<.*>)/;
+
+function styleForHeader(header) {
+  if (header === "Subject") return "header";
+  return "string";
+}
+
+function readToken(stream, state) {
+  if (stream.sol()) {
+    // From last line
+    state.inSeparator = false;
+    if (state.inHeader && stream.match(whitespace)) {
+      // Header folding
+      return null;
+    } else {
+      state.inHeader = false;
+      state.header = null;
+    }
+
+    if (stream.match(separator)) {
+      state.inHeaders = true;
+      state.inSeparator = true;
+      return "atom";
+    }
+
+    var match;
+    var emailPermitted = false;
+    if ((match = stream.match(rfc2822HeaderNoEmail)) ||
+        (emailPermitted = true) && (match = stream.match(rfc2822Header))) {
+      state.inHeaders = true;
+      state.inHeader = true;
+      state.emailPermitted = emailPermitted;
+      state.header = match[1];
+      return "atom";
+    }
+
+    // Use vim's heuristics: recognize custom headers only if the line is in a
+    // block of legitimate headers.
+    if (state.inHeaders && (match = stream.match(header))) {
+      state.inHeader = true;
+      state.emailPermitted = true;
+      state.header = match[1];
+      return "atom";
+    }
+
+    state.inHeaders = false;
+    stream.skipToEnd();
+    return null;
+  }
+
+  if (state.inSeparator) {
+    if (stream.match(email)) return "link";
+    if (stream.match(untilEmail)) return "atom";
+    stream.skipToEnd();
+    return "atom";
+  }
+
+  if (state.inHeader) {
+    var style = styleForHeader(state.header);
+
+    if (state.emailPermitted) {
+      if (stream.match(bracketedEmail)) return style + " link";
+      if (stream.match(untilBracketedEmail)) return style;
+    }
+    stream.skipToEnd();
+    return style;
+  }
+
+  stream.skipToEnd();
+  return null;
+};
+
+CodeMirror.defineMode("mbox", function() {
+  return {
+    startState: function() {
+      return {
+        // Is in a mbox separator
+        inSeparator: false,
+        // Is in a mail header
+        inHeader: false,
+        // If bracketed email is permitted. Only applicable when inHeader
+        emailPermitted: false,
+        // Name of current header
+        header: null,
+        // Is in a region of mail headers
+        inHeaders: false
+      };
+    },
+    token: readToken,
+    blankLine: function(state) {
+      state.inHeaders = state.inSeparator = state.inHeader = false;
+    }
+  };
+});
+
+CodeMirror.defineMIME("application/mbox", "mbox");
+});
-- 
GitLab