Packages
igniter
0.7.6
0.8.2
0.8.1
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.30
0.6.29
0.6.28
0.6.27
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.52
0.5.51
0.5.50
0.5.49
0.5.48
0.5.47
0.5.46
0.5.45
0.5.44
0.5.43
0.5.42
0.5.41
0.5.40
0.5.39
0.5.38
0.5.37
0.5.36
0.5.35
0.5.34
0.5.33
0.5.32
0.5.31
0.5.30
0.5.29
0.5.28
0.5.27
0.5.26
0.5.25
0.5.24
0.5.23
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.78
0.3.77
0.3.76
0.3.75
0.3.74
0.3.73
0.3.72
0.3.71
0.3.70
0.3.69
0.3.68
0.3.67
0.3.66
0.3.65
0.3.64
0.3.63
0.3.62
0.3.61
0.3.60
0.3.59
0.3.58
0.3.57
0.3.56
0.3.55
0.3.54
0.3.53
0.3.52
0.3.51
0.3.50
0.3.49
0.3.48
0.3.47
0.3.46
0.3.45
0.3.44
0.3.43
0.3.42
0.3.41
0.3.40
0.3.39
0.3.38
0.3.37
0.3.36
0.3.35
0.3.34
0.3.33
0.3.32
0.3.31
0.3.30
0.3.29
0.3.28
0.3.27
0.3.26
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A code generation and project patching framework
Current section
Files
Jump to
Current section
Files
lib/igniter/scribe.ex
# SPDX-FileCopyrightText: 2024 igniter contributors <https://github.com/ash-project/igniter/graphs/contributors>
#
# SPDX-License-Identifier: MIT
defmodule Igniter.Scribe do
@moduledoc """
Contains functions for use with the `--scribe` option in Igniter.
See [the guide](/documentation/documenting-tasks.md) for more.
"""
@doc """
Sets the path and title of the document being generated. Only the first call to this is honored.
"""
def start_document(igniter, title, contents, opts \\ []) do
if igniter.assigns[:scribe?] do
igniter
|> append_content("# #{title}")
|> append_content(contents)
|> Igniter.assign(
:test_files,
Map.merge(igniter.assigns[:test_files] || %{}, opts[:files] || %{})
)
else
igniter
end
end
@doc """
Adds a new section to the documentation.
"""
def section(igniter, header, explanation, callback) do
if igniter.assigns[:scribe?] do
current_header = igniter.assigns[:scribe][:header]
nesting_level = igniter.assigns[:scribe][:nesting_level] || 1
header = String.duplicate("#", nesting_level + 1) <> " " <> header
igniter
|> assign(:header, header)
|> assign(:nesting_level, nesting_level + 1)
|> append_content(header)
|> append_content(explanation)
|> callback.()
|> assign(:header, current_header)
|> assign(:nesting_level, nesting_level)
else
callback.(igniter)
end
end
def patch(original_igniter, callback) do
if original_igniter.assigns[:scribe?] do
new_igniter = callback.(original_igniter)
new_igniter.rewrite
|> Enum.reduce(new_igniter, fn source, igniter ->
existing_source =
Rewrite.source(original_igniter.rewrite, source.path)
lang = if Path.extname(source.path) in [".ex", ".eex"], do: "elixir", else: nil
case existing_source do
{:ok, existing_source} ->
if Rewrite.Source.version(existing_source) == Rewrite.Source.version(source) do
igniter
else
TextDiff.format(
existing_source |> Rewrite.Source.get(:content) |> eof_newline(),
source |> Rewrite.Source.get(:content) |> eof_newline(),
color: false,
line_numbers: false,
format: [
separator: ""
]
)
|> IO.iodata_to_binary()
|> String.trim_trailing()
|> String.split("\n")
|> Enum.map_join("\n", fn
" " <> str -> str
other -> other
end)
|> case do
"" ->
igniter
diff ->
igniter
|> append_content("Update `#{source.path}`:")
|> append_content("""
```diff
#{diff}
```
""")
end
end
_ ->
igniter
|> append_content("Create `#{source.path}`:")
|> append_content("""
```#{lang}
#{Rewrite.Source.get(source, :content)}
```
""")
end
end)
else
callback.(original_igniter)
end
end
@doc false
def write(igniter, path) do
File.write!(path, igniter.assigns[:scribe][:content])
igniter
end
defp append_content(igniter, nil) do
igniter
end
defp append_content(igniter, content) do
assign(igniter, :content, (igniter.assigns[:scribe][:content] || "") <> "\n" <> content)
end
defp assign(igniter, key, value) do
Igniter.assign(igniter, :scribe, Map.put(igniter.assigns[:scribe] || %{}, key, value))
end
defp eof_newline(string), do: String.trim_trailing(string) <> "\n"
end