Package: code-writer
Code WriterA Python 3 library with convenience functions for generating code in any
language.Based on the code generation backend inStonethat'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.AlternativesIf your code generation needs are simple, consider using a template language
such asJinja2.Installpip3installcode-writerUsageBasicsYou'll need to importCodeWriter:fromcode_writerimportCodeWriterExamplesYou probably want to write the output ofrender()to a file, but for
illustrative purposes we'll print them.Hello, world.cw=CodeWriter()cw.emit('hello,')withcw.indent():cw.emit('world.')print(cw.render())Output:hello,
    world.Python if statementcw=CodeWriter()cw.emit('if True:')withcw.indent():cw.emit('print("hello, world.")')print(cw.render())Output:ifTrue:print("hello, world.")Rust if statementUseblock()to create an indented block enclosed by curly braces.cw=CodeWriter()withcw.block(before='if true',delim=('{','}')):cw.emit('println!("hello, world.");')print(cw.render())Output:iftrue{println!("hello, world.");}You can also set a default delimiter:cw=CodeWriter(default_delim=('{','}'))Tabscw=CodeWriter(use_tabs=True)Indent two spacescw=CodeWriter(default_dent=2)Generate listscw=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:letli1=[];letli2=[1];letli3=[1,2,3,];letli4=[1,2,3];Generate wrapped textThis is useful for documentation.# Artificially set col width low to show wrapped textcw=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 headerpreamble="""\Thisisapreamble."""cw=CodeWriter()cw.emit_raw(preamble)print(cw.render())Output:This
is
a
preamble.Trim trailing newlinesSometimes you'll want a newline after every iteration of logic, but not for the
last iteration.cw=CodeWriter()withcw.block(before='if true',delim=('{','}')):foriinrange(3):cw.emit('println!("{}");'.format(i))cw.emit()print(cw.render())Output:iftrue{println!("0");println!("1");println!("2");}The gap after the lastprintln!()is undesirable. To fix, do this:cw=CodeWriter()withcw.block(before='if true',delim=('{','}')):foriinrange(3):cw.emit('println!("{}");'.format(i))cw.emit()cw.trim_last_line_if_empty()print(cw.render())Output:iftrue{println!("0");println!("1");println!("2");}Naming conventionsDepending on your target language, you may need to output names that are
PascalCase, camelCase, underscore_delimited, or dash-delimited.fromcode_writerimportfmt_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'assertfmt_camel(text)=='aBHiHoMerryOhYesNoXyz'assertfmt_dashes(text)=='a-b-hi-ho-merry-oh-yes-no-xyz'assertfmt_pascal(text)=='ABHiHoMerryOhYesNoXyz'assertfmt_underscores(text)=='a_b_hi_ho_merry_oh_yes_no_xyz'