33// See https://llvm.org/LICENSE.txt for license information.
44// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55//
6- // Internal helper for Handlebars addon search paths.
6+ // Copyright (c) 2025 Alan de Freitas ([email protected] )7+ //
8+ // Official repository: https://github.com/cppalliance/mrdocs
79//
810
911#ifndef MRDOCS_LIB_GEN_HBS_ADDONPATHS_HPP
1012#define MRDOCS_LIB_GEN_HBS_ADDONPATHS_HPP
1113
1214#include < lib/ConfigImpl.hpp>
1315#include < mrdocs/Support/Path.hpp>
16+ #include < optional>
17+ #include < string>
18+ #include < string_view>
1419#include < vector>
1520
1621namespace mrdocs ::hbs::addon_paths {
1722
23+ /* * Returns the list of addon root directories from the configuration.
24+
25+ This function collects all valid addon root paths by checking
26+ the primary addons directory and any supplemental addon directories
27+ specified in the configuration.
28+
29+ @param config The configuration containing addon path settings.
30+ @return A vector of existing addon root directory paths. The primary
31+ addons directory (if it exists) appears first, followed by
32+ any existing supplemental addon directories in their
33+ configured order.
34+ */
1835inline std::vector<std::string>
1936addonRoots (Config const & config)
2037{
@@ -32,6 +49,128 @@ addonRoots(Config const& config)
3249 return roots;
3350}
3451
52+ /* * Returns directories containing Handlebars partial templates.
53+
54+ For each addon root, this function looks for partial templates in:
55+ 1. `generator/common/partials/` - shared partials for all formats
56+ 2. `generator/<ext>/partials/` - format-specific partials
57+
58+ The order preserves root precedence: for each root, common partials
59+ are loaded first, then format-specific ones. Later roots (supplemental
60+ addons) can override partials from earlier roots.
61+
62+ @param roots The addon root directories to search.
63+ @param ext The output format extension (e.g., "html", "adoc").
64+ @return A vector of existing partial directories in load order.
65+ */
66+ inline std::vector<std::string>
67+ partialDirs (std::vector<std::string> const & roots, std::string_view ext)
68+ {
69+ std::vector<std::string> dirs;
70+ dirs.reserve (roots.size () * 2 );
71+
72+ for (auto const & root : roots)
73+ {
74+ auto const commonDir = files::appendPath (root, " generator" , " common" , " partials" );
75+ if (files::exists (commonDir))
76+ dirs.push_back (commonDir);
77+
78+ auto const formatDir = files::appendPath (root, " generator" , ext, " partials" );
79+ if (files::exists (formatDir))
80+ dirs.push_back (formatDir);
81+ }
82+
83+ return dirs;
84+ }
85+
86+ /* * Returns directories containing JavaScript helper scripts.
87+
88+ For each addon root, this function looks for helper scripts in:
89+ 1. `generator/common/helpers/` - shared helpers for all formats
90+ 2. `generator/<ext>/helpers/` - format-specific helpers
91+
92+ The order preserves root precedence: for each root, common helpers
93+ are loaded first, then format-specific ones. Later roots (supplemental
94+ addons) can override helpers from earlier roots.
95+
96+ @param roots The addon root directories to search.
97+ @param ext The output format extension (e.g., "html", "adoc").
98+ @return A vector of existing helper directories in load order.
99+ */
100+ inline std::vector<std::string>
101+ helperDirs (std::vector<std::string> const & roots, std::string_view ext)
102+ {
103+ std::vector<std::string> dirs;
104+ dirs.reserve (roots.size () * 2 );
105+
106+ for (auto const & root : roots)
107+ {
108+ auto const commonDir = files::appendPath (root, " generator" , " common" , " helpers" );
109+ if (files::exists (commonDir))
110+ dirs.push_back (commonDir);
111+
112+ auto const formatDir = files::appendPath (root, " generator" , ext, " helpers" );
113+ if (files::exists (formatDir))
114+ dirs.push_back (formatDir);
115+ }
116+ return dirs;
117+ }
118+
119+ /* * Returns directories containing layout templates.
120+
121+ For each addon root, this function looks for layout templates in:
122+ `generator/<ext>/layouts/`
123+
124+ Layout templates define the overall page structure (e.g., wrapper.html.hbs,
125+ index.html.hbs). Later roots can override layouts from earlier roots.
126+
127+ @param roots The addon root directories to search.
128+ @param ext The output format extension (e.g., "html", "adoc").
129+ @return A vector of existing layout directories in load order.
130+ */
131+ inline std::vector<std::string>
132+ layoutDirs (std::vector<std::string> const & roots, std::string_view ext)
133+ {
134+ std::vector<std::string> dirs;
135+ dirs.reserve (roots.size ());
136+ for (auto const & root : roots)
137+ {
138+ auto const dir = files::appendPath (root, " generator" , ext, " layouts" );
139+ if (files::exists (dir))
140+ dirs.push_back (dir);
141+ }
142+ return dirs;
143+ }
144+
145+ /* * Searches addon directories for a specific file.
146+
147+ Searches through addon roots in reverse order (supplemental addons
148+ first) to find the specified file. This allows supplemental addons
149+ to override files from the primary addon directory.
150+
151+ @param config The configuration containing addon paths.
152+ @param generator The generator subdirectory (e.g., "html", "common").
153+ @param subdir The subdirectory within the generator (e.g., "layouts").
154+ @param filename The filename to search for.
155+ @return The full path to the file if found, or std::nullopt.
156+ */
157+ inline std::optional<std::string>
158+ findFile (
159+ Config const & config,
160+ std::string_view generator,
161+ std::string_view subdir,
162+ std::string_view filename)
163+ {
164+ auto roots = addonRoots (config);
165+ for (auto it = roots.rbegin (); it != roots.rend (); ++it)
166+ {
167+ std::string candidate = files::appendPath (*it, " generator" , generator, subdir, filename);
168+ if (files::exists (candidate))
169+ return candidate;
170+ }
171+ return std::nullopt ;
172+ }
173+
35174} // namespace mrdocs::hbs::addon_paths
36175
37176#endif // MRDOCS_LIB_GEN_HBS_ADDONPATHS_HPP
0 commit comments