Hong Minhee avatar Hong Minhee committed 4d11e30

Added HTTP lexer.

Comments (0)

Files changed (2)

httpdomain/doc/index.rst

 
       The posts tagged with `tag` that the user (`user_id`) wrote.
 
+      **Example request**:
+
+      .. sourcecode:: http
+
+         GET /users/123/posts/web HTTP/1.1
+         Host: example.com
+         Accept: application/json, text/javascript
+
+      **Example response**:
+
+      .. sourcecode:: http
+
+         HTTP/1.1 200 OK
+         Vary: Accept
+         Content-Type: text/javascript
+
+         [
+           {
+             "post_id": 12345,
+             "author_id": 123,
+             "tags": ["server", "web"],
+             "subject": "I tried Nginx"
+           },
+           {
+             "post_id": 12346,
+             "author_id": 123,
+             "tags": ["html5", "standards", "web"],
+             "subject": "We go to HTML 5"
+           }
+         ]
+
       :query sort: one of ``hit``, ``created-at``
       :query offset: offset number. default is 0
       :query limit: limit number. default is 30
 
        The posts tagged with `tag` that the user (`user_id`) wrote.
 
+       **Example request**:
+
+       .. sourcecode:: http
+
+          GET /users/123/posts/web HTTP/1.1
+          Host: example.com
+          Accept: application/json, text/javascript
+
+       **Example response**:
+
+       .. sourcecode:: http
+
+          HTTP/1.1 200 OK
+          Vary: Accept
+          Content-Type: text/javascript
+
+          [
+            {
+              "post_id": 12345,
+              "author_id": 123,
+              "tags": ["server", "web"],
+              "subject": "I tried Nginx"
+            },
+            {
+              "post_id": 12346,
+              "author_id": 123,
+              "tags": ["html5", "standards", "web"],
+              "subject": "We go to HTML 5"
+            }
+          ]
+
        :query sort: one of ``hit``, ``created-at``
        :query offset: offset number. default is 0
        :query limit: limit number. default is 30

httpdomain/sphinxcontrib/httpdomain.py

 from docutils import nodes
 from docutils.parsers.rst.roles import set_classes
 
+from pygments.lexer import RegexLexer, bygroups
+from pygments.lexers import get_lexer_by_name
+from pygments.token import Literal, Text,  Operator, Keyword, Name, Number
+from pygments.util import ClassNotFound
+
 from sphinx import addnodes
 from sphinx.roles import XRefRole
 from sphinx.domains import Domain, ObjType, Index
                 yield (path, path, method, info[0], anchor, 1)
 
 
+class HTTPLexer(RegexLexer):
+    """Lexer for HTTP sessions."""
+
+    name = 'HTTP'
+    aliases = ['http']
+
+    flags = re.DOTALL
+
+    def header_callback(self, match):
+        if match.group(1).lower() == 'content-type':
+            content_type = match.group(5).strip()
+            if ';' in content_type:
+                content_type = content_type[:content_type.find(';')].strip()
+            self.content_type = content_type
+        yield match.start(1), Name.Attribute, match.group(1)
+        yield match.start(2), Text, match.group(2)
+        yield match.start(3), Operator, match.group(3)
+        yield match.start(4), Text, match.group(4)
+        yield match.start(5), Literal, match.group(5)
+        yield match.start(6), Text, match.group(6)
+
+    def content_callback(self, match):
+        content_type = getattr(self, 'content_type', None)
+        content = match.group()
+        offset = match.start()
+        if content_type:
+            from pygments.lexers import get_lexer_for_mimetype
+            try:
+                lexer = get_lexer_for_mimetype(content_type)
+            except ClassNotFound:
+                pass
+            else:
+                for idx, token, value in lexer.get_tokens_unprocessed(content):
+                    yield offset + idx, token, value
+                return
+        yield offset, Text, content
+
+    tokens = {
+        'root': [
+            (r'(GET|POST|PUT|DELETE|HEAD|OPTIONS|TRACE)( +)([^ ]+)( +)'
+             r'(HTTPS?)(/)(1\.[01])(\r?\n|$)',
+             bygroups(Name.Function, Text, Name.Namespace, Text,
+                      Keyword.Reserved, Operator, Number, Text),
+             'headers'),
+            (r'(HTTPS?)(/)(1\.[01])( +)(\d{3})( +)([^\r\n]+)(\r?\n|$)',
+             bygroups(Keyword.Reserved, Operator, Number, Text, Number,
+                      Text, Name.Exception, Text),
+             'headers'),
+        ],
+        'headers': [
+            (r'([^\s:]+)( *)(:)( *)([^\r\n]+)(\r?\n|$)', header_callback),
+            (r'\r?\n', Text, 'content')
+        ],
+        'content': [
+            (r'.+', content_callback)
+        ]
+    }
+
+
 def setup(app):
     app.add_domain(HTTPDomain)
+    try:
+        get_lexer_by_name('http')
+    except ClassNotFound:
+        app.add_lexer('http', HTTPLexer())
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.