├── .editorconfig ├── .gitignore ├── .travis.yml ├── AUTHORS ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── pycco ├── __init__.py ├── compat.py ├── generate_index.py ├── languages.py └── main.py ├── pycco_resources └── __init__.py ├── requirements.test.txt ├── requirements.txt ├── setup.py ├── tests ├── __init__.py └── test_pycco.py └── tox.ini /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://EditorConfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = LF 8 | 9 | [*.py] 10 | indent_style = space 11 | indent_size = 4 12 | 13 | [*.css] 14 | indent_style = space 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .coverage 2 | *.pyc 3 | /Pycco.egg-info 4 | build/* 5 | dist/* 6 | docs/* 7 | /tags 8 | 9 | .cache 10 | .hypothesis 11 | .ropeproject 12 | 13 | .DS_Store 14 | 15 | .tox -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: python 3 | python: 4 | - '2.7' 5 | - '3.6' 6 | install: 7 | - 'pip install -r requirements.txt' 8 | - 'pip install -r requirements.test.txt' 9 | script: 10 | - 'py.test --cov=pycco tests/' 11 | - 'python -m pycco.main pycco/main.py' 12 | after_success: 13 | - coveralls 14 | matrix: 15 | include: 16 | - python: 2.7 17 | env: TOXENV=py27 18 | install: pip install tox 19 | script: tox 20 | - python: 3.6 21 | env: TOXENV=py36 22 | install: pip install tox 23 | script: tox 24 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alexis Metaireau 2 | Anders Bergh 3 | Antti Kaihola 4 | Christopher Gateley 5 | Jack Miller 6 | Morgan Goose 7 | Nick Fitzgerald 8 | Steffen Kampmann 9 | Zach Smith 10 | goosemo 11 | khamidou 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Pycco 2 | 3 | [Zach Smith](http://zdsmith.com) is the current maintainer of this project. 4 | 5 | ## Help Us Out 6 | 7 | Feel free to contribute by opening a pull request on this project's [GitHub repo](https://github.com/pycco-docs/pycco). All requests with documented and tested code will be gladly reviewed. 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Nick Fitzgerald 2 | Copyright (c) 2016 Zachary Smith 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | 22 | Parts of Pycco are taken from Docco, see http://github.com/jashkenas/docco for 23 | more information. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | 888888b. 3 | 888 Y88b 4 | 888 888 5 | 888 d88P 888 888 .d8888b .d8888b .d88b. 6 | 8888888P" 888 888 d88P" d88P" d88""88b 7 | 888 888 888 888 888 888 888 8 | 888 Y88b 888 Y88b. Y88b. Y88..88P 9 | 888 "Y88888 "Y8888P "Y8888P "Y88P" 10 | 888 11 | Y8b d88P 12 | "Y88P" 13 | ``` 14 | 15 | Pycco is a Python port of Docco: the original quick-and-dirty, hundred-line- 16 | long, literate-programming-style documentation generator. For more information, 17 | see: 18 | 19 | https://pycco-docs.github.io/pycco/ 20 | 21 | Others: 22 | 23 | CoffeeScript (Original) - http://jashkenas.github.com/docco/ 24 | 25 | Ruby - http://rtomayko.github.com/rocco/ 26 | 27 | Sh - http://rtomayko.github.com/shocco/ 28 | 29 | [](https://travis-ci.org/pycco-docs/pycco) 30 | [](https://coveralls.io/github/pycco-docs/pycco?branch=master) 31 | -------------------------------------------------------------------------------- /pycco/__init__.py: -------------------------------------------------------------------------------- 1 | from .main import * # noqa 2 | 3 | __all__ = ("process",) 4 | -------------------------------------------------------------------------------- /pycco/compat.py: -------------------------------------------------------------------------------- 1 | try: 2 | pycco_unichr = unichr 3 | except NameError: 4 | pycco_unichr = chr 5 | 6 | 7 | def compat_items(d): 8 | try: 9 | return d.iteritems() 10 | except AttributeError: 11 | return d.items() 12 | -------------------------------------------------------------------------------- /pycco/generate_index.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is the module responsible for automatically generating an HTML index of 3 | all documentation files generated by Pycco. 4 | """ 5 | import re 6 | from os import path 7 | 8 | from pycco.compat import compat_items 9 | from pycco_resources import pycco_template 10 | 11 | 12 | __all__ = ('generate_index',) 13 | 14 | 15 | def build_tree(file_paths, outdir): 16 | tree = {} 17 | for file_path in file_paths: 18 | entry = { 19 | 'path': file_path, 20 | 'relpath': path.relpath(file_path, outdir) 21 | } 22 | path_steps = entry['relpath'].split(path.sep) 23 | add_file(entry, path_steps, tree) 24 | 25 | return tree 26 | 27 | 28 | def add_file(entry, path_steps, tree): 29 | """ 30 | :param entry: A dictionary containing a path to a documentation file, and a 31 | relative path to the same file. 32 | :param path_steps: A list of steps in a file path to look within. 33 | """ 34 | node, subpath = path_steps[0], path_steps[1:] 35 | if node not in tree: 36 | tree[node] = {} 37 | 38 | if subpath: 39 | add_file(entry, subpath, tree[node]) 40 | 41 | else: 42 | tree[node]['entry'] = entry 43 | 44 | 45 | def generate_tree_html(tree): 46 | """ 47 | Given a tree representing HTML file paths, return an HTML table plotting 48 | those paths. 49 | """ 50 | items = [] 51 | for node, subtree in sorted(compat_items(tree)): 52 | if 'entry' in subtree: 53 | html = u'
"
463 |
464 | # The end of each Pygments highlight block.
465 | highlight_end = "
' in pre_block 159 | assert '' in pre_block 160 | 161 | 162 | def test_generate_documentation(): 163 | p.generate_documentation(PYCCO_SOURCE, outdir=tempfile.gettempdir()) 164 | 165 | 166 | @given(booleans(), booleans(), data()) 167 | def test_process(preserve_paths, index, data): 168 | lang_name = data.draw(sampled_from([l["name"] for l in supported_languages.values()])) 169 | p.process([PYCCO_SOURCE], preserve_paths=preserve_paths, 170 | index=index, 171 | outdir=tempfile.gettempdir(), 172 | language=lang_name) 173 | 174 | 175 | @patch('pygments.lexers.guess_lexer') 176 | def test_process_skips_unknown_languages(mock_guess_lexer): 177 | class Name: 178 | name = 'this language does not exist' 179 | mock_guess_lexer.return_value = Name() 180 | 181 | with pytest.raises(ValueError): 182 | p.process(['LICENSE'], outdir=tempfile.gettempdir(), skip=False) 183 | 184 | p.process(['LICENSE'], outdir=tempfile.gettempdir(), skip=True) 185 | 186 | 187 | one_or_more_chars = text(min_size=1, max_size=255) 188 | paths = lists(one_or_more_chars, min_size=1, max_size=30) 189 | @given( 190 | lists(paths, min_size=1, max_size=255), 191 | lists(one_or_more_chars, min_size=1, max_size=255) 192 | ) 193 | def test_generate_index(path_lists, outdir_list): 194 | file_paths = [os.path.join(*path_list) for path_list in path_lists] 195 | outdir = os.path.join(*outdir_list) 196 | generate_index.generate_index(file_paths, outdir=outdir) 197 | 198 | 199 | def test_flatten_sources(tmpdir): 200 | sources = [str(tmpdir)] 201 | expected_sources = [] 202 | 203 | # Setup the base dir 204 | td = tmpdir.join("test.py") 205 | td.write("#!/bin/env python") 206 | expected_sources.append(str(td)) 207 | 208 | # Make some more directories, each with a file present 209 | for d in ["foo", "bar", "buzz"]: 210 | dd = tmpdir.mkdir(d) 211 | dummy_file = dd.join("test.py") 212 | dummy_file.write("#!/bin/env python") 213 | expected_sources.append(str(dummy_file)) 214 | 215 | # Get the flattened version of the base directory 216 | flattened = p._flatten_sources(sources) 217 | 218 | # Make sure that the lists are the same 219 | assert sorted(expected_sources) == sorted(flattened) 220 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27,py36,codestyle 3 | 4 | [testenv] 5 | deps = -rrequirements.test.txt 6 | commands = pytest 7 | 8 | [testenv:codestyle] 9 | deps = pycodestyle 10 | # E501 - line too long 11 | commands = pycodestyle --ignore=E501 pycco 12 | --------------------------------------------------------------------------------