total rebase
[anni] / lib / pleroma / docs / translator / compiler.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Docs.Translator.Compiler do
6   @external_resource "config/description.exs"
7   @raw_config Pleroma.Config.Loader.read("config/description.exs")
8   @raw_descriptions @raw_config[:pleroma][:config_description]
9
10   defmacro __before_compile__(_env) do
11     strings =
12       __MODULE__.descriptions()
13       |> __MODULE__.extract_strings()
14
15     quote do
16       def placeholder do
17         unquote do
18           Enum.map(
19             strings,
20             fn {path, type, string} ->
21               ctxt = msgctxt_for(path, type)
22
23               quote do
24                 Pleroma.Web.Gettext.dpgettext_noop(
25                   "config_descriptions",
26                   unquote(ctxt),
27                   unquote(string)
28                 )
29               end
30             end
31           )
32         end
33       end
34     end
35   end
36
37   def descriptions do
38     Pleroma.Web.ActivityPub.MRF.config_descriptions()
39     |> Enum.reduce(@raw_descriptions, fn description, acc -> [description | acc] end)
40     |> Pleroma.Docs.Generator.convert_to_strings()
41   end
42
43   def extract_strings(descriptions) do
44     descriptions
45     |> Enum.reduce(%{strings: [], path: []}, &process_item/2)
46     |> Map.get(:strings)
47   end
48
49   defp process_item(entity, acc) do
50     current_level =
51       acc
52       |> process_desc(entity)
53       |> process_label(entity)
54
55     process_children(entity, current_level)
56   end
57
58   defp process_desc(acc, %{description: desc} = item) do
59     %{
60       strings: [{acc.path ++ [key_for(item)], "description", desc} | acc.strings],
61       path: acc.path
62     }
63   end
64
65   defp process_desc(acc, _) do
66     acc
67   end
68
69   defp process_label(acc, %{label: label} = item) do
70     %{
71       strings: [{acc.path ++ [key_for(item)], "label", label} | acc.strings],
72       path: acc.path
73     }
74   end
75
76   defp process_label(acc, _) do
77     acc
78   end
79
80   defp process_children(%{children: children} = item, acc) do
81     current_level = Map.put(acc, :path, acc.path ++ [key_for(item)])
82
83     children
84     |> Enum.reduce(current_level, &process_item/2)
85     |> Map.put(:path, acc.path)
86   end
87
88   defp process_children(_, acc) do
89     acc
90   end
91
92   def msgctxt_for(path, type) do
93     "config #{type} at #{Enum.join(path, " > ")}"
94   end
95
96   defp convert_group({_, group}) do
97     group
98   end
99
100   defp convert_group(group) do
101     group
102   end
103
104   def key_for(%{group: group, key: key}) do
105     "#{convert_group(group)}-#{key}"
106   end
107
108   def key_for(%{group: group}) do
109     convert_group(group)
110   end
111
112   def key_for(%{key: key}) do
113     key
114   end
115
116   def key_for(_) do
117     nil
118   end
119 end