def load_docs(docs, name=''): """ Load a documentation file from the folder docs. Files will be copied to the build directory relative to docs. Any directories found within the docs directory will be loaded in their own subsection of the navigation and table of contents where the name of the section is the name of the directory. :param docs: The directory to load documentation from :param name: The name of the navigation section """ global nav, table directories = [] if not os.path.exists(docs.replace('source', 'build')): os.mkdir(docs.replace('source', 'build')) for file in os.listdir(docs): path = docs + '/' + file if os.path.isfile(path) and path.endswith('.md'): id = file.replace('.', '_') nav += nav_content.format(id, re.sub(r'(")|(<!--.*-->)', '', fileutil.read(path))) nav += nav_item.format(id, '%/' + name + '/' + file[:-3] + '.html', file[2:-3] .replace('_', ' ') .replace('index', 'Overview')) table += table_item.format('%/' + name + '/' + file[:-3] + '.html', file[2:-3] .replace('_', ' ') .replace('index', 'Overview')) fileutil.write(docs.replace('source', 'build') + '/' + file, fileutil.read(path)) elif os.path.isdir(path) and not file.startswith('.'): directories.append((file, path)) for file, path in directories: nav += nav_sec_start.format(file) table += table_sec_start.format(file) load_docs(path, name=file) nav += nav_sec_end table += table_sec_end
def __createIndexHtml(jsonData, dataChengjiao): colors = [ '#EF5350', '#FFA726', '#FFEA00', '#66BB6A', '#29B6F6', '#8D6E63', '#7E57C2', '#FF5252', '#EEFF41', '#283593', '#CE93D8' ] dataAvg = {} datasets = [] labels = [] count = 0 for key in jsonData: dataset = {} data = [] dataset['label'] = key dataset['data'] = data dataset['backgroundColor'] = colors[count] dataset['borderColor'] = colors[count] dataset['fill'] = False for value in jsonData[key]: dataTime = value[0] price = value[1] data.append(str(price)) if count == 0: labels.append(str(format(dataTime))) count += 1 datasets.append(dataset) dataAvg['datasets'] = datasets dataAvg['labels'] = labels htmlContent = read('./frontend/vm/index.vm') htmlContent = htmlContent.replace('${dataAvg}', json.dumps(dataAvg)) htmlContent = htmlContent.replace('${dataChengjiao}', dataChengjiao) write('./frontend/index.html', htmlContent)
def load_source(name, directory, build): """ Parses and processes the docstrings from all python files in the given directory and copies them to the given build directory. Each file is added as an item to the navigation list and table of contents under a section with the given name. :param name: The name of the navigation and table of contents section :param directory: The directory to load documentation from :param build: The build directory """ global nav, table nav += nav_sec_start.format(name) table += table_sec_start.format(name) if not os.path.exists(build + '/' + name): os.mkdir(build + '/' + name) for file in sorted(os.listdir(directory)): path = directory + '/' + file if os.path.isfile(path) and path.endswith('.py') and '__init__' not in path: docstrings = re.findall( r'((((((def)|(class))\s[^\n]*?:\s*)?"{3}.*?)"{3})|(\n#[^\n]*\n[^\n]* =))', fileutil.read(path), re.DOTALL ) parsed = '\n***\n'.join([format_docstring(doc[0]) for doc in docstrings]) parsed += '\n***\nView the [source](%/../../pyxam/{})'.format( path.replace(os.path.dirname(os.path.dirname(__file__)), '') ) fileutil.write(build + '/' + name + '/' + file.replace('.py', '.md'), parsed) id = file.replace('.', '_') nav += nav_content.format(id, parsed.replace('"', '')) nav += nav_item.format(id, '%/' + name + '/' + file[:-3] + '.html', file[:-3]) table += table_item.format('%/' + name + '/' + file[:-3] + '.html', file[:-3]) nav += nav_sec_end table += table_sec_end
def parse(): """ Converts mixed files from source to an intermediate based on the extension of the template file. Once converted the intermediate is run through the default filters and the extension formatter's processors. :return: A list of intermediates corresponding to each of the mixed files """ intermediates, parser = [], get_format(options.state.template()) if not parser['format']: raise FormatError('This format is export only!') # Loop through all weaved files for file in fileutil.with_extension('.tex'): options.post('Using ' + parser['name'] + ' format to parse ' + file) intermediate = util.Map({ 'ast': [], 'src': parser['parser_preprocessor'](fileutil.read(file)), 'fmt': parser, 'name': file.replace('.tex', '') }) intermediate.ast = parse_tokens(intermediate.src, parser) for default_filter in config.default_filters: intermediate.ast = default_filter(intermediate.ast) intermediate = parser['parser_postprocessor'](intermediate) intermediates.append(intermediate) fileutil.write(options.state.cwd() + '/parsed-ast', ''.join(str_token(intermediate.ast))) options.post('Successfully parsed', parser['name'] + '.') return intermediates
def pdf_compile(): """ Compiles any tex files in the out directory to PDF or DVI depending on what `compile_format` is set to. All additional files (aux, log, tex) are removed once compilation completes. """ options.state.cwd(options.state.out()) options.post('Compiling', len(fileutil.with_extension('.tex')), 'files.') for file in fileutil.with_extension('.tex'): if compile_format == 'dvi': fileutil.write(file, '%&latex\n' + fileutil.read(file)) try: fileutil.remove(file.replace('.tex', '.pdf')) except: pass for i in range(options.state.recomps()): lib_loader.pdflatex(file) fileutil.remove(fileutil.with_extension(['.aux', '.log', '.tex'])) options.post('Finished compiling.\n')
def mix(n, row, default=False): """ Takes an exam version and row of data and prepares a file for the formatter. If weaving is enabled a .mix with the correct name is weaved with the inline code at the start of the file. If weaving is disabled a .tex file is prepared for the formatter directly. :param n: The exam version :param row: The row of data """ logging.info(str(row)) version = str(chr(n + ord('A')) if options.state.alphabetize() else n + 1) if options.state.noweave(): fileutil.write( options.state.cwd() + '/' + config.filename.format(version=version, name=row['name'].replace(' ', '_').strip(), number=row['number']).strip('_') + '.tex', fileutil.read(options.state.template())) else: path = options.state.cwd() + '/' + config.filename.format( version=version, name=row['name'].replace(' ', '_').strip(), number=row['number']).strip('_') + '.tex' fileutil.write( path, '<%\n' + inline.replace('{number}', str(n)).replace( '{version}', str(version)).replace( '{student_first_name}', config.placeholder[options.state.format()] if default else str(row['first'])).replace( '{student_last_name}', config.placeholder[options.state.format()] if default else str(row['last'])).replace( '{student_name}', config.placeholder[options.state.format()] if default else str(row['name'])).replace( '{student_number}', config.placeholder[options.state.format()] if default else str(row['number'])) + '\n%>' + fileutil.read(options.state.template())) lib_loader.weave(path) fileutil.write( path, '<%\n' + inline.replace('{number}', str(n)).replace( '{version}', str(version)).replace( '{student_first_name}', config.placeholder[options.state.format()] if default else str(row['first'])).replace( '{student_last_name}', config.placeholder[options.state.format()] if default else str(row['last'])).replace( '{student_name}', config.placeholder[options.state.format()] if default else str(row['name'])).replace( '{student_number}', config.placeholder[options.state.format()] if default else str(row['number'])) + '\n%>' + fileutil.read(options.state.cwd() + '/' + config.filename.format( version=version, name=row['name'].replace(' ', '_'), number=row['number']).strip('_') + '.tex')) lib_loader.weave(path)
def compose(intermediates): """ Converts intermediates to a source file based on the format option. The formatter's processors are run on the intermediate and final source. If the source is being converted to the same format it came from the intermediate will be discarded in favour of the original source. :param intermediates: A list of intermediates """ try: composer = formats[options.state.format()] except: raise FormatError('Unknown format') for intermediate in intermediates: composed = intermediate.src # If not already in native format if intermediate.fmt != composer: intermediate = composer['composer_preprocessor'](intermediate) fileutil.write(options.state.cwd() + '/composed-ast', ''.join(str_token(intermediate.ast))) composed = ''.join([pack(token, composer) for token in intermediate.ast]).strip() composed = composer['composer_postprocessor'](composed) fileutil.write(intermediate.name + '.cmp', composed) options.post('Successfully composed', composer['name'] + '.')
def compile_doc(build, doc): """ Converts the given file from markdown to HTML and then copies it to the build directory. :param build: The directory of the file to compile :param doc: The file to compile """ pyxam.pyxam.start([ '-w', # Disable weaving '-f', 'html', # Convert to HTML '-o', build, # Output to the build directory '-t', 'doc', # Title the file doc '-htt', config.template_directory + '/docs.html', doc # Use the docs template ]) buffer = fileutil.read(build + '/doc_v1.html') fileutil.remove(doc) fileutil.remove(build + '/doc_v1.html') fileutil.write( doc.replace('.md', '.html'), buffer .replace('<!-- nav -->', nav) .replace('<!-- table -->', table + '</ul>') .replace('%/', url + '/') )
def mix(n, row, default=False): """ Takes an exam version and row of data and prepares a file for the formatter. If weaving is enabled a .mix with the correct name is weaved with the inline code at the start of the file. If weaving is disabled a .tex file is prepared for the formatter directly. :param n: The exam version :param row: The row of data """ logging.info(str(row)) version = str(chr(n + ord('A')) if options.state.alphabetize() else n + 1) if options.state.noweave(): fileutil.write( options.state.cwd() + '/' + config.filename.format(version=version, name=row['name'].replace(' ', '_').strip(), number=row['number']).strip('_') + '.tex', fileutil.read(options.state.template()) ) else: path = options.state.cwd() + '/' + config.filename.format(version=version, name=row['name'].replace(' ', '_').strip(), number=row['number']).strip('_') + '.tex' fileutil.write( path, '<%\n' + inline .replace('{number}', str(n)) .replace('{version}', str(version)) .replace('{student_first_name}', config.placeholder[options.state.format()] if default else str(row['first'])) .replace('{student_last_name}', config.placeholder[options.state.format()] if default else str(row['last'])) .replace('{student_name}', config.placeholder[options.state.format()] if default else str(row['name'])) .replace('{student_number}', config.placeholder[options.state.format()] if default else str(row['number'])) + '\n%>' + fileutil.read(options.state.template()) ) lib_loader.weave(path) fileutil.write( path, '<%\n' + inline .replace('{number}', str(n)) .replace('{version}', str(version)) .replace('{student_first_name}', config.placeholder[options.state.format()] if default else str(row['first'])) .replace('{student_last_name}', config.placeholder[options.state.format()] if default else str(row['last'])) .replace('{student_name}', config.placeholder[options.state.format()] if default else str(row['name'])) .replace('{student_number}', config.placeholder[options.state.format()] if default else str(row['number'])) + '\n%>' + fileutil.read(options.state.cwd() + '/' + config.filename.format(version=version, name=row['name'].replace(' ', '_'), number=row['number']).strip('_') + '.tex') ) lib_loader.weave(path)