<!-- livebook:{"persist_outputs":true} -->

# Usage

```elixir
Mix.install([:kino, :ymlr, :yaml_elixir])

full = %{
  "atom" => :ymlr,
  "date" => ~D[2018-11-15],
  "date_time" => ~U[2018-11-15 11:00:00Z],
  "list" => ["item 1", "item 2", "item 3"],
  "nested list" => [["item 1.1", "item 1.2"], ["item 2.1", "item 2.2", "item 2.3"]],
  "nested map" => %{
    "some" => %{
      "nested" => ["data"]
    }
  },
  "numbers" => %{
    "float" => 3.14159265,
    "hex" => 0x0B1010,
    "int" => 123,
    "oct" => 0o777
  },
  "numbers as strings" => %{
    "float" => "3.14159265",
    "hex" => "0x0b1010",
    "int" => "123",
    "oct" => "0o777"
  },
  "string" => "hello world",
  "string (multiline)" => "hello\nworld"
}

simple_1 = %{"message" => "hello world"}
simple_2 = %{message: "nice to be here"}
:ok
```

<!-- livebook:{"output":true} -->

```
Resolving Hex dependencies...
Dependency resolution completed:
New:
  kino 0.9.2
  table 0.1.2
  yamerl 0.10.0
  yaml_elixir 2.9.0
  ymlr 3.0.1
* Getting kino (Hex package)
* Getting ymlr (Hex package)
* Getting yaml_elixir (Hex package)
* Getting yamerl (Hex package)
* Getting table (Hex package)
==> table
Compiling 5 files (.ex)
Generated table app
==> ymlr
Compiling 2 files (.ex)
Generated ymlr app
==> kino
Compiling 39 files (.ex)
Generated kino app
===> Analyzing applications...
===> Compiling yamerl
==> yaml_elixir
Compiling 6 files (.ex)
Generated yaml_elixir app
```

<!-- livebook:{"output":true} -->

```
:ok
```

## Encoding a single document

[![Run in Livebook](https://livebook.dev/badge/v1/pink.svg)](https://livebook.dev/run?url=https%3A%2F%2Fgithub.com%2Fufirstgroup%2Fymlr%2Fblob%2Fmain%2Fusage.livemd)

Note: We defined document data as variables `full`, `simple_1` and `simple_2` in the setup block at the top of this livebook.

<!-- livebook:{"reevaluate_automatically":true} -->

```elixir
full
|> Ymlr.document!()
|> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
atom: ymlr
date:
  2018-11-15
date_time:
  2018-11-15T11:00:00Z
list:
  - item 1
  - item 2
  - item 3
nested list:
  - - item 1.1
    - item 1.2
  - - item 2.1
    - item 2.2
    - item 2.3
nested map:
  some:
    nested:
      - data
numbers:
  float: 3.14159265
  hex: 725008
  int: 123
  oct: 511
numbers as strings:
  float: '3.14159265'
  hex: '0x0b1010'
  int: '123'
  oct: '0o777'
string: hello world
string (multiline): |-
  hello
  world

```

<!-- livebook:{"output":true} -->

```
:ok
```

<!-- livebook:{"reevaluate_automatically":true} -->

```elixir
simple_1
|> Ymlr.document()
```

<!-- livebook:{"output":true} -->

```
{:ok, "---\nmessage: hello world\n"}
```

## Encoding multiple documents

```elixir
[simple_1, simple_2]
|> Ymlr.documents!()
|> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
message: hello world

---
message: nice to be here

```

<!-- livebook:{"output":true} -->

```
:ok
```

<!-- livebook:{"reevaluate_automatically":true} -->

```elixir
[simple_1, simple_2]
|> Ymlr.documents()
```

<!-- livebook:{"output":true} -->

```
{:ok, "---\nmessage: hello world\n\n---\nmessage: nice to be here\n"}
```

## Adding comments

To add a comment at the top of the YAML document, pass a tuple in the form `{comment, document}` to any of the functions.

<!-- livebook:{"reevaluate_automatically":true} -->

```elixir
{"Single comment", simple_1}
|> Ymlr.document!()
|> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
# Single comment
message: hello world

```

<!-- livebook:{"output":true} -->

```
:ok
```

The first element of the tuple can be a list of comments:

<!-- livebook:{"reevaluate_automatically":true} -->

```elixir
{["First comment", "Second Comment", "Third Comment"], simple_1}
|> Ymlr.document!()
|> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
# First comment
# Second Comment
# Third Comment
message: hello world

```

<!-- livebook:{"output":true} -->

```
:ok
```

Multiple documents with comments:

```elixir
[
  {["First doc, first comment", "First doc, second Comment", "First doc,  Comment"], simple_1},
  {["Second doc, first comment", "Second doc, second comment"], simple_2}
]
|> Ymlr.documents!()
|> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
# First doc, first comment
# First doc, second Comment
# First doc,  Comment
message: hello world

---
# Second doc, first comment
# Second doc, second comment
message: nice to be here

```

<!-- livebook:{"output":true} -->

```
:ok
```

## Encoding Atom Map Keys

By default, atoms as map keys are encoded as strings (without the leading
colon). If you want atoms to be encoded with a leading colon in order to be able
to parse it later using [`YamlElixir`'s `atoms`
option](https://hexdocs.pm/yaml_elixir/readme.html#support-for-atoms), you can
pass `atoms: true` as second argument to any of the `Ymlr` module's functions:

```elixir
simple_2
|> Ymlr.document!(atoms: true)
|> YamlElixir.read_from_string!(atoms: true)
```

<!-- livebook:{"output":true} -->

```
%{message: "nice to be here"}
```

## Encode maps with keys sorted

Maps in elixir, implemented by erlang `:maps`, internally are `flatmap`s or `hashmap`s by size.
Large maps will be encoded in strange order.

```elixir
map = Map.new(1..33, &{&1, &1})
map |> Ymlr.document!() |> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
4: 4
25: 25
8: 8
...

```

By using `:sort_maps` option, ymlr will encode all entries sorted.

```elixir
map |> Ymlr.document!(sort_maps: true) |> IO.puts()
```

<!-- livebook:{"output":true} -->

```
---
1: 1
2: 2
3: 3
...

```
