codeshow/__init__.py

import pygments.lexers

import pygments.formatters.html

import pygments.styles.monokai

import os

import jinja2

import errno

import util

import markdown

# need to define templates before importing format (which depends on them)

templates = {}

templates_dir = os.path.join(os.path.dirname(__file__), 'templates')

for name in os.listdir(templates_dir):

with file(os.path.join(templates_dir, name)) as f:

templates[name] = jinja2.Template(f.read())

import format

class Generator:

def __init__(self, source_directory, output_directory, ignore_paths, site44, custom_types):

self.source_directory = source_directory

self.output_directory = output_directory

self.ignore_paths = ignore_paths

self.site44 = site44

self.use_extensions = not site44

self.custom_types = custom_types

def generate(self):

if self.site44:

with file(os.path.join(self.output_directory, 'mimetypes.site44.txt'), 'wt') as f:

f.write('/raw/**/* text/plain\n/file/**/* text/html\n')

for d in ['tree', 'file', 'raw']: os.mkdir(os.path.join(self.output_directory, d))

self.css_file = os.path.join(self.output_directory, 'styles.css')

with file(self.css_file, 'wt') as f:

f.write(templates['css'].render(pygments_styles = pygments.formatters.html.HtmlFormatter(style=pygments.styles.monokai.MonokaiStyle).get_style_defs('.highlight')))

for dirpath, dirnames, filenames in os.walk(self.source_directory):

# weed out ignored paths

dirnames[:] = filter(lambda dirname: os.path.abspath(os.path.join(dirpath, dirname)) not in self.ignore_paths and not dirname.startswith('.'), dirnames)

reldir = os.path.relpath(dirpath, self.source_directory)

if reldir != '.': os.mkdir(os.path.join(self.output_directory, 'tree', reldir))

for d in ['file', 'raw']:

try: os.mkdir(os.path.join(self.output_directory, d, reldir))

except OSError, e:

if e.errno != errno.EEXIST:

raise e

included_files = []

for filename in filenames:

file_path = os.path.join(dirpath, filename)

print 'Processing %s' % file_path

if util.is_binary(file_path): continue

included_files.append(filename)

self.generate_file(file_path)

self.generate_index(dirpath, dirnames, filenames, included_files)

def generate_file(self, source_file):

relpath = os.path.relpath(source_file, self.source_directory)

output_file = os.path.join(self.output_directory, 'file', relpath)

output_raw = os.path.join(self.output_directory, 'raw', relpath)

html_extension = self.use_extensions and '.html' or ''

raw_extension = self.use_extensions and '.txt' or ''

relcss = os.path.relpath(self.css_file, os.path.dirname(output_file)).replace('\\', '/')

formatter = format.CodeShowFormatter(encoding='utf-8',

style=pygments.styles.monokai.MonokaiStyle,

cssfile=relcss,

noclobber_cssfile=True,

title=relpath.replace('\\', '/'),

raw_path=os.path.relpath(output_raw, os.path.dirname(output_file)).replace('\\', '/')+raw_extension,

use_extensions=self.use_extensions)

name_for_lexer = source_file

extension = os.path.splitext(source_file)[1].lstrip('.').lower()

if extension in self.custom_types: name_for_lexer = '.' + self.custom_types[extension]

try: lexer = pygments.lexers.get_lexer_for_filename(name_for_lexer)

except: lexer = pygments.lexers.TextLexer()

with file(source_file) as infile: code = infile.read().decode('utf-8-sig')

with file(output_file+html_extension, 'wt') as outfile:

pygments.highlight(code, lexer, formatter, outfile)

with file(output_raw+raw_extension, 'wt') as outfile:

outfile.write(code.encode('utf-8'))

def generate_index(self, dirpath, dirnames, filenames, included_files):

reldir = os.path.relpath(dirpath, self.source_directory)

if reldir == '.':

index_path = os.path.join(self.output_directory, 'index.html')

else:

index_path = os.path.join(self.output_directory, 'tree', reldir + '.html')

readme = None

is_markdown = False

if os.path.isfile(os.path.join(dirpath, 'readme.md')):

is_markdown = True

with file(os.path.join(dirpath, 'readme.md')) as f:

readme = markdown.markdown(f.read())

else:

filename = None

for name in ['readme', 'readme.txt']:

if os.path.isfile(os.path.join(dirpath, name)):

filename = name

if filename is not None:

with file(os.path.join(dirpath, filename)) as f:

formatter = format.CodeShowFormatter(encoding='utf-8', style=pygments.styles.monokai.MonokaiStyle, nowrap=True)

readme = pygments.highlight(f.read().decode('utf-8-sig'), pygments.lexers.TextLexer(), formatter)

with file(index_path, 'wt') as f:

f.write(templates['directory'].render(

reldir = reldir != '.' and reldir.replace('\\', '/') + '/' or '',

relroot = os.path.relpath(self.output_directory, os.path.dirname(index_path)).replace('\\', '/'),

relcss = os.path.relpath(self.css_file, os.path.dirname(index_path)).replace('\\', '/'),

directories = [(name, not os.path.islink(os.path.join(dirpath, name))) for name in dirnames],

files = [(name, name in included_files) for name in filenames],

readme = readme,

is_markdown = is_markdown,

use_extensions = self.use_extensions

))

def generate(source_directory, output_directory, ignore_paths, site44):

Generator(source_directory, output_directory, ignore_paths, site44).generate()