Skip to content

Commit

Permalink
Implement basic Lua output support (#1745)
Browse files Browse the repository at this point in the history
* Implement basic Lua output support

Ref #1700

Basic but working serialization to Lua tables.

* Escape larger set of characters in Lua output

Started with a minimum of replacements, this should be more complete,
tho not all substitutions are strictly required in Lua.

* Print simple keys unquoted in Lua output

String keys that satisfy the requirements for variable names can be used
as keys without quotes in tables.

* Quote Lua keywords in table keys

Keywords are not valid as unquoted keys, thus must be quoted

* Make output of unquoted Lua table keys optional

Generally safer and simpler to not do it.

* Hook up settings for Lua output

* Allow special characters in Lua prefix and suffix

--lua-suffix='});^M' didn't work, so taking this approach instead

* Panic on unhandled YAML Kind in Lua encoder

* Handle YAML case varied booleans in Lua encoder

* Handle special-case numbers in Lua encoder

* Reject unhandled scalar Tags in Lua encoder

* Add note about how Lua nil is unsuitable as table key

Could add some context tracking in the future to allow rejecting nil in
a table key context.

* Return error instead of panic in Lua encoder

* Add initial test for Lua encoder

Boilerplate mostly copied from toml_test.go

* Additional Lua output tests

* Generate Lua encoder documentation

Mostly just for the boilerplate

* Convert octal for Lua output

Lua doesn't have the 0oNNN syntax for octal integers, only decimal and
hexadecimal, hence those can be passed trough as is while octal needs
special treatment.

* Implement indentation in in Lua output

* Respect string Style in Lua encoder

Lua has 'single', "double" and [[ long ]] strings.

* Expand Lua examples

* Output line comments in Lua output

* Implement Lua globals output mode
  • Loading branch information
Zash authored Aug 11, 2023
1 parent 9b40829 commit d302d75
Show file tree
Hide file tree
Showing 7 changed files with 759 additions and 1 deletion.
5 changes: 5 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ yq -P sample.json
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipProcInst, "xml-skip-proc-inst", yqlib.ConfiguredXMLPreferences.SkipProcInst, "skip over process instructions (e.g. <?xml version=\"1\"?>)")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredXMLPreferences.SkipDirectives, "xml-skip-directives", yqlib.ConfiguredXMLPreferences.SkipDirectives, "skip over directives (e.g. <!DOCTYPE thing cat>)")

rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocPrefix, "lua-prefix", yqlib.ConfiguredLuaPreferences.DocPrefix, "prefix")
rootCmd.PersistentFlags().StringVar(&yqlib.ConfiguredLuaPreferences.DocSuffix, "lua-suffix", yqlib.ConfiguredLuaPreferences.DocSuffix, "suffix")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.UnquotedKeys, "lua-unquoted", yqlib.ConfiguredLuaPreferences.UnquotedKeys, "output unquoted string keys (e.g. {foo=\"bar\"})")
rootCmd.PersistentFlags().BoolVar(&yqlib.ConfiguredLuaPreferences.Globals, "lua-globals", yqlib.ConfiguredLuaPreferences.Globals, "output keys as top-level global variables")

rootCmd.PersistentFlags().BoolVarP(&nullInput, "null-input", "n", false, "Don't read input, simply evaluate the expression given. Useful for creating docs from scratch.")
rootCmd.PersistentFlags().BoolVarP(&noDocSeparators, "no-doc", "N", false, "Don't print document separators (---)")

Expand Down
2 changes: 2 additions & 0 deletions cmd/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ func createEncoder(format yqlib.PrinterOutputFormat) (yqlib.Encoder, error) {
return yqlib.NewTomlEncoder(), nil
case yqlib.ShellVariablesOutputFormat:
return yqlib.NewShellVariablesEncoder(), nil
case yqlib.LuaOutputFormat:
return yqlib.NewLuaEncoder(yqlib.ConfiguredLuaPreferences), nil
}
return nil, fmt.Errorf("invalid encoder: %v", format)
}
Expand Down
144 changes: 144 additions & 0 deletions pkg/yqlib/doc/usage/lua.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@

## Basic example
Given a sample.yml file of:
```yaml
---
country: Australia # this place
cities:
- Sydney
- Melbourne
- Brisbane
- Perth
```
then
```bash
yq -o=lua '.' sample.yml
```
will output
```lua
return {
["country"] = "Australia"; -- this place
["cities"] = {
"Sydney",
"Melbourne",
"Brisbane",
"Perth",
};
};
```

## Unquoted keys
Uses the `--lua-unquoted` option to produce a nicer-looking output.

Given a sample.yml file of:
```yaml
---
country: Australia # this place
cities:
- Sydney
- Melbourne
- Brisbane
- Perth
```
then
```bash
yq -o=lua '.' sample.yml
```
will output
```lua
return {
country = "Australia"; -- this place
cities = {
"Sydney",
"Melbourne",
"Brisbane",
"Perth",
};
};
```

## Globals
Uses the `--lua-globals` option to export the values into the global scope.

Given a sample.yml file of:
```yaml
---
country: Australia # this place
cities:
- Sydney
- Melbourne
- Brisbane
- Perth
```
then
```bash
yq -o=lua '.' sample.yml
```
will output
```lua
country = "Australia"; -- this place
cities = {
"Sydney",
"Melbourne",
"Brisbane",
"Perth",
};
```

## Elaborate example
Given a sample.yml file of:
```yaml
---
hello: world
tables:
like: this
keys: values
? look: non-string keys
: True
numbers:
- decimal: 12345
- hex: 0x7fabc123
- octal: 0o30
- float: 123.45
- infinity: .inf
- not: .nan

```
then
```bash
yq -o=lua '.' sample.yml
```
will output
```lua
return {
["hello"] = "world";
["tables"] = {
["like"] = "this";
["keys"] = "values";
[{
["look"] = "non-string keys";
}] = true;
};
["numbers"] = {
{
["decimal"] = 12345;
},
{
["hex"] = 0x7fabc123;
},
{
["octal"] = 24;
},
{
["float"] = 123.45;
},
{
["infinity"] = (1/0);
},
{
["not"] = (0/0);
},
};
};
```

Loading

0 comments on commit d302d75

Please sign in to comment.