Skip to content

braincore/code-writer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Code Writer Latest Version Build Status

A Python 3 library with convenience functions for generating code in any language.

Based on the code generation backend in Stone that's used to generate code in many languages: C#, Java, Python, Ruby, Rust, Typescript, and more.

Why?

You know all of the pains with code generation (coding, build process, maintenance), but have decided you have no other choice. This library makes generating code a little bit more manageable.

Alternatives

If your code generation needs are simple, consider using a template language such as Jinja2.

Install

pip3 install code-writer

Usage

Basics

You'll need to import CodeWriter:

from code_writer import CodeWriter

Examples

You probably want to write the output of render() to a file, but for illustrative purposes we'll print them.

Hello, world.

cw = CodeWriter()
cw.emit('hello,')
with cw.indent():
    cw.emit('world.')
print(cw.render())

Output:

hello,
    world.

Python if statement

cw = CodeWriter()
cw.emit('if True:')
with cw.indent():
    cw.emit('print("hello, world.")')
print(cw.render())

Output:

if True:
    print("hello, world.")

Rust if statement

Use block() to create an indented block enclosed by curly braces.

cw = CodeWriter()
with cw.block(before='if true', delim=('{', '}')):
    cw.emit('println!("hello, world.");')
print(cw.render())

Output:

if true {
    println!("hello, world.");
}

You can also set a default delimiter:

cw = CodeWriter(default_delim=('{', '}'))

Tabs

cw = CodeWriter(use_tabs=True)

Indent two spaces

cw = CodeWriter(default_dent=2)

Generate lists

cw = CodeWriter()
cw.emit_list([], ('[', ']'), before='let li1 = ', after=';')
cw.emit_list(['1'], ('[', ']'), before='let li2 = ', after=';')
cw.emit_list(['1', '2', '3'], ('[', ']'), before='let li3 = ', after=';')
cw.emit_list(['1', '2', '3'], ('[', ']'), before='let li4 = ', after=';', compact=True)
print(cw.render())

Output:

let li1 = [];
let li2 = [1];
let li3 = [
    1,
    2,
    3,
];
let li4 = [1,
           2,
           3];

Generate wrapped text

This is useful for documentation.

# Artificially set col width low to show wrapped text
cw = CodeWriter(default_width=25)
cw.emit('/**')
cw.emit_wrapped_text(
    '@param param1 an explanation of what this argument does.',
    prefix=' * ',
    indent_after_first=True,
)
cw.emit('*/')
print(cw.render())

Output:

/**
 * @param param1 an
 *     explanation of
 *     what this argument
 *     does.
*/

Emit a preamble or header

preamble = """\
This
is
a
preamble.
"""
cw = CodeWriter()
cw.emit_raw(preamble)
print(cw.render())

Output:

This
is
a
preamble.

Trim trailing newlines

Sometimes you'll want a newline after every iteration of logic, but not for the last iteration.

cw = CodeWriter()
with cw.block(before='if true', delim=('{', '}')):
    for i in range(3):
        cw.emit('println!("{}");'.format(i))
        cw.emit()
print(cw.render())

Output:

if true {
    println!("0");

    println!("1");

    println!("2");

}

The gap after the last println!() is undesirable. To fix, do this:

cw = CodeWriter()
with cw.block(before='if true', delim=('{', '}')):
    for i in range(3):
        cw.emit('println!("{}");'.format(i))
        cw.emit()
    cw.trim_last_line_if_empty()
print(cw.render())

Output:

if true {
    println!("0");

    println!("1");

    println!("2");
}

Naming conventions

Depending on your target language, you may need to output names that are PascalCase, camelCase, underscore_delimited, or dash-delimited.

from code_writer import fmt_camel, fmt_dashes, fmt_pascal, fmt_underscores
# The input name can be a mix of formatting. These helpers will aggressively
# split the word and re-assemble as desired.
text = 'a-B-HiHo-merryOh_yes_no_XYZ'
assert fmt_camel(text) == 'aBHiHoMerryOhYesNoXyz'
assert fmt_dashes(text) == 'a-b-hi-ho-merry-oh-yes-no-xyz'
assert fmt_pascal(text) == 'ABHiHoMerryOhYesNoXyz'
assert fmt_underscores(text) == 'a_b_hi_ho_merry_oh_yes_no_xyz'

About

A Python 3 library with convenience functions for generating code in any language.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages