Currently for MusicXML import, we are able to go from MusicXML to Alda []ScoreUpdate. The following 3 PRs combined will introduce an Alda code generator to complete the import process:
This PR introduces a code formatter, translating ASTNode to Alda code.
func FormatASTToCode(root ASTNode, out io.Writer, opts ...formatterOption) error {
Notes
Whitespaces
The formatter is quite rudimentary, but has basic handling of whitespacing (indents, spaces, line wrapping) while maintaining the integrity of the generated code.
For indents, we essentially maintain an indentation level. Within parts, voices, and event seqs, we indent.
For wrapping, we format "texts" or tokens that are single strings. Between texts, we can wrap the line.
Variable Definitions
Variable definitions are tricky as I've noted in code comments. As a summary, the problem is all definition nodes must be on the same line as the variable name. The easiest way I found to handle this is to introduce the varDefState enum, which introduces some significant complexity into the formatter.
Testing
We piggyback and use the parseTestCase to also automatically test formatting. Like with ast-gen, we ensure the "round-trip" formatted then parsed AST is identical to the actual correct AST.
Comments
Currently comments are dropped when scanning, so they will be dropped for a round-trip format (code -> AST -> code).
I've spent a couple hours trying my hand at the changes necessary to retain comments to the AST level. I think this change is not worth it, as it's quite complicated and touches sensitive code. Plus MusicXML import doesn't produce comments, so the change is not necessary for this main use case. Plus the formatter itself is not very good, so I don't think it'll really standalone.
I've left supporting comments as a TODO.
Commands
The formatter is not quite good enough in my opinion to standalone as it's own command to actually use. Combined with the fact that we don't even support comments, we will introduce an experimental hidden alda format command.
Background
Currently for MusicXML import, we are able to go from MusicXML to Alda
[]ScoreUpdate
. The following 3 PRs combined will introduce an Alda code generator to complete the import process:This PR introduces a code formatter, translating
ASTNode
to Alda code.Notes
Whitespaces
The formatter is quite rudimentary, but has basic handling of whitespacing (indents, spaces, line wrapping) while maintaining the integrity of the generated code.
Variable Definitions
Variable definitions are tricky as I've noted in code comments. As a summary, the problem is all definition nodes must be on the same line as the variable name. The easiest way I found to handle this is to introduce the
varDefState
enum, which introduces some significant complexity into the formatter.Testing
We piggyback and use the
parseTestCase
to also automatically test formatting. Like with ast-gen, we ensure the "round-trip" formatted then parsed AST is identical to the actual correct AST.Comments
Currently comments are dropped when scanning, so they will be dropped for a round-trip format (code -> AST -> code).
I've spent a couple hours trying my hand at the changes necessary to retain comments to the AST level. I think this change is not worth it, as it's quite complicated and touches sensitive code. Plus MusicXML import doesn't produce comments, so the change is not necessary for this main use case. Plus the formatter itself is not very good, so I don't think it'll really standalone.
I've left supporting comments as a TODO.
Commands
The formatter is not quite good enough in my opinion to standalone as it's own command to actually use. Combined with the fact that we don't even support comments, we will introduce an experimental hidden
alda format
command.