Package: compact-json
compact-jsoncompact-jsonis a JSON formatter that produces configurably compact JSON that remains human-readable.Any given container is formatted in one of three ways:Python lists or dicts will be written on a single line, if their contents aren't too complex and the resulting line wouldn't be too long.lists can be written on multiple lines, with multiple items per line, as long as those items aren't too complex.Otherwise, each dict property or array item is written beginning on its own line, indented one step deeper than its parent.The following JSON is the standard output from runningpython3 -mjson.tool:{"widget":{"debug":"on","window":{"title":"Sample Konfabulator Widget","name":"main_window","width":500,"height":500},"image":{"src":"Images/Sun.png","name":"sun1","hOffset":250,"vOffset":250,"alignment":"center"},"text":{"data":"Click Here","size":36,"style":"bold","name":"text1","hOffset":250,"vOffset":100,"alignment":"center","onMouseUp":"sun1.opacity = (sun1.opacity / 100) * 90;"}}}Thewindowandimageobjects are fairly short so when formatted withcompact-jsonthey can be formated on a single line. With the default setting thetextobject is still too long to fit on one line, but this can be configured to be longer:{"widget":{"debug":"on","window":{"title":"Sample Konfabulator Widget","name":"main_window","width":500,"height":500},"image":{"src":"Images/Sun.png","name":"sun1","hOffset":250,"vOffset":250,"alignment":"center"},"text":{"data":"Click Here","size":36,"style":"bold","name":"text1","hOffset":250,"vOffset":100,"alignment":"center","onMouseUp":"sun1.opacity = (sun1.opacity / 100) * 90;"}}}Installationpython3-mpipinstallcompact-jsonUsageAs a python package,compact-jsonis instantiated with aFormatterclass that has a range of properties to configure the formatting:fromcompact_jsonimportFormatter,EolStyleformatter=Formatter()formatter.indent_spaces=2formatter.max_inline_complexity=10formatter.json_eol_style=EolStyle.LF# Format the JSON contents:withopen("input.json","r")asf:obj=json.load(f)json_string=formatter.serialize(obj)print(json_string)# Create a new JSON file with formatted JSON contents:withopen("input.json","r")asf:obj=json.load(f)formatter.dump(obj,output_file="output.json",newline_at_eof=True)Runtime warningsUnlike the builtinjsonpackage,compact-jsonwill issue runtime warnings when dictionary keys are forced to strings or overwritten to ensure that the resulting JSON is well-formed:>>>fromcompact_jsonimportFormatter>>>Formatter().serialize({100:"error",200:"had",300:["a","little","lamb"],"100":"mary"})/path/src/compact_json/formatter.py:346:RuntimeWarning:coercingkeyvalue100tostringwarnings.warn(f"converting key value{k}to string",RuntimeWarning)/path/src/compact_json/formatter.py:346:RuntimeWarning:coercingkeyvalue200tostringwarnings.warn(f"converting key value{k}to string",RuntimeWarning)/path/src/compact_json/formatter.py:346:RuntimeWarning:coercingkeyvalue300tostringwarnings.warn(f"converting key value{k}to string",RuntimeWarning)/path/src/compact_json/formatter.py:349:RuntimeWarning:duplicatekeyvalue100warnings.warn(f"duplicate key value{k}",RuntimeWarning)'{ "100": "mary", "200": "had", "300": ["a", "little", "lamb"] }'Command-line usageWhen installed frompipa command-line utilitycompact-jsonis installed which has some useful defaults and most of the parameters available inFormattercan be set on the command-line:usage:compact-json[-h][-V][--output-filename[OUTPUT_FILENAME...]][--crlf][--max-inline-lengthN][--max-inline-complexityN][--max-compact-list-complexityN][--bracket-padding{simple,nested}][--indentN][--tab-indent][--justify-numbers][--prefix-stringSTRING][--align-properties][json...]FormatJSONintocompact,humanreadableform

positionalarguments:jsonJSONfile(s)toparse(orstdinwith"-")optionalarguments:-h,--helpshowthishelpmessageandexit-V,--version--output-filename[OUTPUT_FILENAME...],-out[OUTPUT_FILENAME...]Theoutputfilename(s).Ifempty,nonewJSONfile(s)willbesaved.Ifprovided,thenumberofoutputfilenamesmustmatchthatoftheinputfiles.--crlfUseWindows-styleCRLFlineendings--max-inline-lengthNLimitinlineelementstoNchars,excludingindentationandleadingpropertynames(default=50)--max-inline-complexityNMaximumnesting:0=basictypes,1=dict/list,2=all(default=2)--max-compact-list-complexityNMaximumnestingovermultiplelines(default1)--bracket-padding{simple,nested}Ifnestedpadding,addspecesinsideoutsidebrackesfornestedlists/dicts--indentNIndentNspaces(default=4)--tab-indentUsetabstoindent--justify-numbersRight-alignnumberswithmatchingprecision--prefix-stringSTRINGStringattachedtothebeginningofeveryline--align-propertiesAlignpropertynamesofexpandeddicts--unicodeTreatstringsasunicodeEastAsiancharacterscompact-jsoncan be used in a shell pipeline to read from stdin when passed-as the file argument.Format optionsTheFormatterclass has the following properties:json_eol_styleDictates what sort of line endings to use.EolStyle.LFis Unix-style line endings (the default) andEolStyle.CRLFWindows-style.max_inline_lengthMaximum length of a complex element on a single line. This includes only the data for the inlined element not indentation or leading property names. The default is 80.max_inline_complexityMaximum nesting level that can be displayed on a single line. A primitive type or an empty list or dict has a complexity of 0. A dict or list has a complexity of 1 greater than its most complex child. The default is 2.max_compact_list_complexityMaximum nesting level that can be arranged spanning multiple lines, with multiple items per line. The default is 1.nested_bracket_paddingIf an inlined list or dict contains other lists or dicts, settingnested_bracket_paddingtoTruewill include spaces inside the outer brackets. The default isTrue.See alsosimple_bracket_padding.simple_bracket_paddingIf an inlined list or dict does NOT contain other lists/dicts, settingsimple_bracket_paddingtoTruewill include spaces inside the brackets. The default isFalse.See alsonested_bracket_padding.colon_paddingIfTrue(the default), includes a space after property colons.comma_paddingIfTrue(the default), includes a space after commas separating list items and dict properties.always_expand_depthDepth at which lists/dicts are always fully expanded, regardless of other settings-1 = none. This is the default0 = root node only1 = root node and its children.indent_spacesNumber of spaces to use per indent level (unlessuse_tab_to_indentisTrue). The default is 4.use_tab_to_indentUses a single tab per indent level, instead of spaces. The default isFalse.table_dict_minimum_similarityValue from 0 to 100 indicating how similar collections of inline dicts need to be to be formatted as a table. A group of dicts that don't have any property names in common has a similarity of zero. A group of dicts that all contain the exact same property names has a similarity of 100. Setting this to a value > 100 disables table formatting with dicts as rows. The default is 75.table_list_minimum_similarityValue from 0 to 100 indicating how similar collections of inline lists need to be to be formatted as a table. Similarity for lists refers to how similar they are in length; if they all have the same length their similarity is 100. Setting this to a value > disables table formatting with lists as rows. The default is 75.align_expanded_property_namesIfTrue, property names of expanded dicts are padded to the same size. The default isFalse.dont_justify_numbersIfTrue, numbers won't be right-aligned with matching precision. The default isFalse.prefix_stringString attached to the beginning of every line, before regular indentation.ensure_asciiIfTrue(the default), the output is guaranteed to have all incoming non-ASCII characters escaped. Ifensure_asciiisFalse, these characters will be output as-is.east_asian_string_widthsIfTrue, format strings using unicodedata.east_asian_width rather than simple string lengthsCreditscompact-jsonis primarily a Python port ofFracturedJsonJsbyj-brooke. FractureJson is also
an excellentVisual Studio Code extension. This package has no other relationship
with this original code, and hence all the bugs are my own.LicenseAll code in this repository is licensed under theMIT LicenseContributeContributions are greatly appreciated and welcomed. Please follow theproject guidanceon how to contribute.