summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZach Smith <zd@zdsmith.com>2018-04-25 20:49:46 -0400
committerZach Smith <zd@zdsmith.com>2018-04-25 20:49:46 -0400
commitc815be6017bbe884ce88bb41f7ec0369ca77914d (patch)
tree252baa48e821dadfd2cdc9e610c2e325183943e0
parentbedb3da55d611153388004184222a26190ce3202 (diff)
downloadpycco-c815be6017bbe884ce88bb41f7ec0369ca77914d.tar.gz
Factor out languages to their own module
-rw-r--r--pycco/languages.py60
-rw-r--r--pycco/main.py113
-rw-r--r--tests/test_pycco.py12
3 files changed, 104 insertions, 81 deletions
diff --git a/pycco/languages.py b/pycco/languages.py
new file mode 100644
index 0000000..48288f0
--- /dev/null
+++ b/pycco/languages.py
@@ -0,0 +1,60 @@
+"""
+A list of the languages that Pycco supports, mapping the file extension to
+the name of the Pygments lexer and the symbol that indicates a comment. To
+add another language to Pycco's repertoire, add it here.
+"""
+
+__all__ = ("supported_languages",)
+
+HASH = "#"
+SLASH_STAR = "/*"
+STAR_SLASH = "*/"
+SLASH_SLASH = "//"
+DASH_DASH = "--"
+
+def lang(name, comment_symbol, multistart=None, multiend=None):
+ result = {
+ "name": name,
+ "comment_symbol": comment_symbol
+ }
+ if multistart is not None and multiend is not None:
+ result["multistart"] = multistart
+ result["multiend"] = multiend
+ return result
+
+
+c_lang = lang("c", SLASH_SLASH, SLASH_STAR, STAR_SLASH)
+
+supported_languages = {
+ ".coffee": lang("coffee-script", HASH, "###", "###"),
+
+ ".pl": lang("perl", HASH),
+
+ ".sql": lang("sql", DASH_DASH, SLASH_STAR, STAR_SLASH),
+
+ ".sh": lang("bash", HASH),
+
+ ".c": c_lang,
+
+ ".h": c_lang,
+
+ ".cl": c_lang,
+
+ ".cpp": lang("cpp", SLASH_SLASH),
+
+ ".js": lang("javascript", SLASH_SLASH, SLASH_STAR, STAR_SLASH),
+
+ ".rb": lang("ruby", HASH, "=begin", "=end"),
+
+ ".py": lang("python", HASH, '"""', '""'),
+
+ ".scm": lang("scheme", ";;", "#|", "|#"),
+
+ ".lua": lang("lua", DASH_DASH, "--[[", "--]]"),
+
+ ".erl": lang("erlang", "%%"),
+
+ ".tcl": lang("tcl", HASH),
+
+ ".hs": lang("haskell", DASH_DASH, "{-", "-}"),
+}
diff --git a/pycco/main.py b/pycco/main.py
index affd38d..9e4a3c9 100644
--- a/pycco/main.py
+++ b/pycco/main.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-from __future__ import print_function
+from __future__ import print_function, absolute_import
# Import our external dependencies.
import optparse
@@ -9,7 +9,8 @@ import sys
import time
from os import path
-import pycco.generate_index as generate_index
+from pycco.generate_index import generate_index
+from pycco.languages import supported_languages
import pygments
from markdown import markdown
from pycco_resources import css as pycco_css
@@ -69,7 +70,7 @@ def _generate_documentation(file_path, code, outdir, preserve_paths, language):
"""
Helper function to allow documentation generation without file handling.
"""
- language = get_language(file_path, code, language=language)
+ language = get_language(file_path, code, language_name=language)
sections = parse(code, language)
highlight(sections, language, preserve_paths=preserve_paths, outdir=outdir)
return generate_html(file_path, sections, preserve_paths=preserve_paths, outdir=outdir)
@@ -313,55 +314,10 @@ def generate_html(source, sections, preserve_paths=True, outdir=None):
# === Helpers & Setup ===
-# A list of the languages that Pycco supports, mapping the file extension to
-# the name of the Pygments lexer and the symbol that indicates a comment. To
-# add another language to Pycco's repertoire, add it here.
-languages = {
- ".coffee": {"name": "coffee-script", "comment_symbol": "#",
- "multistart": '###', "multiend": '###'},
-
- ".pl": {"name": "perl", "comment_symbol": "#"},
-
- ".sql": {"name": "sql", "comment_symbol": "--"},
-
- ".sh": {"name": "bash", "comment_symbol": "#"},
-
- ".c": {"name": "c", "comment_symbol": "//",
- "multistart": "/*", "multiend": "*/"},
-
- ".h": {"name": "c", "comment_symbol": "//",
- "multistart": "/*", "multiend": "*/"},
-
- ".cpp": {"name": "cpp", "comment_symbol": "//"},
-
- ".cl": {"name": "c", "comment_symbol": "//",
- "multistart": "/*", "multiend": "*/"},
-
- ".js": {"name": "javascript", "comment_symbol": "//",
- "multistart": "/*", "multiend": "*/"},
-
- ".rb": {"name": "ruby", "comment_symbol": "#",
- "multistart": "=begin", "multiend": "=end"},
-
- ".py": {"name": "python", "comment_symbol": "#",
- "multistart": '"""', "multiend": '"""'},
-
- ".scm": {"name": "scheme", "comment_symbol": ";;",
- "multistart": "#|", "multiend": "|#"},
-
- ".lua": {"name": "lua", "comment_symbol": "--",
- "multistart": "--[[", "multiend": "--]]"},
-
- ".erl": {"name": "erlang", "comment_symbol": "%%"},
-
- ".tcl": {"name": "tcl", "comment_symbol": "#"},
-
- ".hs": {"name": "haskell", "comment_symbol": "--",
- "multistart": "{-", "multiend": "-}"},
-}
-
-# Build out the appropriate matchers and delimiters for each language.
-for ext, l in languages.items():
+def compile_language(l):
+ """
+ Build out the appropriate matchers and delimiters for each language.
+ """
language_name = l["name"]
comment_symbol = l["comment_symbol"]
@@ -382,32 +338,37 @@ for ext, l in languages.items():
l["lexer"] = lexers.get_lexer_by_name(language_name)
-def get_language(source, code, language=None):
- """Get the current language we're documenting, based on the extension."""
+for entry in supported_languages.values():
+ compile_language(entry)
- if language is not None:
- for l in languages.values():
- if l["name"] == language:
- return l
+def get_language(source, code, language_name=None):
+ """
+ Get the current language we're documenting, based on the extension.
+ """
+ if language_name is not None:
+ for entry in supported_languages.values():
+ if entry["name"] == language_name:
+ return entry
else:
- raise ValueError("Unknown forced language: " + language)
+ raise ValueError("Unknown forced language: {}".format(language_name))
- m = re.match(r'.*(\..+)', os.path.basename(source)) if source else None
- if m and m.group(1) in languages:
- return languages[m.group(1)]
- else:
- try:
- lang = lexers.guess_lexer(code).name.lower()
- for l in languages.values():
- if l["name"] == lang:
- return l
- else:
- raise ValueError()
- except ValueError:
- # If pygments can't find any lexers, it will raise its own
- # subclass of ValueError. We will catch it and raise ours
- # for consistency.
- raise ValueError("Can't figure out the language!")
+ if source:
+ m = re.match(r'.*(\..+)', os.path.basename(source))
+ if m and m.group(1) in supported_languages:
+ return supported_languages[m.group(1)]
+
+ try:
+ language_name = lexers.guess_lexer(code).name.lower()
+ for entry in supported_languages.values():
+ if entry["name"] == language_name:
+ return entry
+ else:
+ raise ValueError()
+ except ValueError:
+ # If pygments can't find any lexers, it will raise its own
+ # subclass of ValueError. We will catch it and raise ours
+ # for consistency.
+ raise ValueError("Can't figure out the language!")
def destination(filepath, preserve_paths=True, outdir=None):
@@ -541,7 +502,7 @@ def process(sources, preserve_paths=True, outdir=None, language=None,
if index:
with open(path.join(outdir, "index.html"), "wb") as f:
- f.write(generate_index.generate_index(generated_files, outdir))
+ f.write(generate_index(generated_files, outdir))
__all__ = ("process", "generate_documentation")
diff --git a/tests/test_pycco.py b/tests/test_pycco.py
index 6a98eda..f5ab936 100644
--- a/tests/test_pycco.py
+++ b/tests/test_pycco.py
@@ -1,3 +1,4 @@
+from __future__ import absolute_import
import copy
import os
import tempfile
@@ -8,16 +9,17 @@ from hypothesis import given, example
from hypothesis.strategies import lists, text, booleans, choices, none
import pycco.generate_index as generate_index
+from pycco.languages import supported_languages
import pycco.main as p
-PYTHON = p.languages['.py']
+PYTHON = supported_languages['.py']
PYCCO_SOURCE = 'pycco/main.py'
FOO_FUNCTION = """def foo():\n return True"""
def get_language(choice):
- return choice(list(p.languages.values()))
+ return choice(list(supported_languages.values()))
@given(lists(text()), text())
@@ -75,10 +77,10 @@ def test_comment_with_only_cross_ref():
@given(text(), text())
def test_get_language_specify_language(source, code):
assert p.get_language(
- source, code, language="python") == p.languages['.py']
+ source, code, language_name="python") == supported_languages['.py']
with pytest.raises(ValueError):
- p.get_language(source, code, language="non-existent")
+ p.get_language(source, code, language_name="non-existent")
@given(text() | none())
@@ -155,7 +157,7 @@ def test_generate_documentation():
@given(booleans(), booleans(), choices())
def test_process(preserve_paths, index, choice):
- lang_name = choice([l["name"] for l in p.languages.values()])
+ lang_name = choice([l["name"] for l in supported_languages.values()])
p.process([PYCCO_SOURCE], preserve_paths=preserve_paths,
index=index,
outdir=tempfile.gettempdir(),