3
3
from jinja2 import Environment
4
4
5
5
6
- def github_path (toolname , scripts_tools ):
7
- """Finds GitHub path for a tool in GRASS GIS with subtool handling"""
8
-
9
- auto_generated_indexes = [
10
- "database" ,
11
- "db" ,
12
- "display" ,
13
- "general" ,
14
- "imagery" ,
15
- "miscellaneous" ,
16
- "postscript" ,
17
- "raster" ,
18
- "raster3d" ,
19
- "temporal" ,
20
- "vector" ,
21
- ]
22
-
23
- # Special cases for documentation pages that don't match the pattern matching scheme
24
- special_docs = [
25
- {"name" : "projectionintro" , "path" : "doc" },
26
- {"name" : "grass_database" , "path" : "doc" },
27
- {"name" : "databaseintro" , "path" : "db" },
28
- ]
29
-
30
- # Exit early if toolname is empty
31
- if not toolname :
6
+ def github_path (toolname : str , source_docs : dict [str , str ]):
7
+ """Return the GitHub path for the given toolname"""
8
+ try :
9
+ return source_docs [toolname ]
10
+ except KeyError :
32
11
return None
33
12
34
- # Handle special cases
35
- if toolname in [x ["name" ] for x in special_docs ]:
36
- return next ((x ["path" ] for x in special_docs if x ["name" ] == toolname ), None )
37
-
38
- # Convert filter() results to a list
39
- tool_matches = list (filter (lambda x : toolname in x , scripts_tools ))
40
-
41
- # print(f"Tool Matches: {tool_matches}")
42
-
43
- # If there's exactly one match, return it immediately
44
- if len (tool_matches ) == 1 :
45
- return tool_matches [0 ]
46
-
47
- # Prioritize exact matches
48
- exact_match = next ((x for x in tool_matches if x .endswith (toolname )), None )
49
- # print(f"Exact - Tool Matches: {exact_match}")
50
- if toolname in auto_generated_indexes :
51
- # print(f"Exact Match - Autogenerated: {exact_match}")
52
- return None
53
- if exact_match :
54
- return exact_match
55
-
56
- # Prefer major categories (raster, vector, imagery, temporal, etc.)
57
- category_match = next (
58
- (x for x in tool_matches if not x .startswith ("scripts/" )), None
59
- )
60
- # print(f"Category - Tool Matches: {category_match}")
61
- if category_match :
62
- return category_match
63
-
64
- # Check for subtools in the same directory (e.g., r.sim -> r.sim.water, r.sim.sediment)
65
- subtool_prefix = toolname + "." # Ensure it matches the full prefix
66
- sub_tool_matches = [x for x in tool_matches if x .startswith (subtool_prefix )]
67
-
68
- # print(f"Subtool - Tool Matches: {sub_tool_matches}")
69
- # If exactly one subtool match exists, return it
70
- if len (sub_tool_matches ) == 1 :
71
- return sub_tool_matches [0 ]
72
-
73
- # If multiple subtools exist, prioritize based on name length (more specific subtools come first)
74
- if sub_tool_matches :
75
- sub_tool_matches .sort (key = len ) # Shorter names first
76
- return sub_tool_matches [0 ] # Return the most specific match
77
-
78
- # Handle special case for "intro" pages
79
- # print(f"Intro Doc - Matches: {tool_matches}")
80
- if toolname .endswith ("intro" ):
81
- return toolname .replace ("intro" , "" )
82
-
83
- # Special case for gui/wxpython/docs
84
- if toolname .startswith ("g." ):
85
- # print(f"GUI Docs: {toolname}")
86
- tool_dir = toolname .split ("." )[- 1 ]
87
- return f"gui/wxpython/{ tool_dir } /{ toolname } "
88
-
89
- # If nothing else, return the first available match
90
- return tool_matches [0 ] if tool_matches else None
91
-
92
13
93
14
def on_env (env : Environment , config , files ):
94
15
"""Enable loopcontrols extension in Jinja2"""
@@ -103,20 +24,32 @@ def on_config(config):
103
24
store it in MkDocs extra config. These are used to generate
104
25
the correct links to the documentation in GitHub.
105
26
"""
106
- scripts_dir = Path ("source" )
107
- scripts_tools = []
108
- url_pattern = re . compile (
109
- r"https://github.com/OSGeo/grass/tree/main/([^ )]+)"
110
- ) # Read the mkdocs.yml file
27
+ source_dir = Path ("source" )
28
+
29
+ # Dict to store the documentation path for each tool in GitHub
30
+ # the key is the doc name and the value is the path in the GitHub repository
31
+ source_docs = {}
111
32
112
- for file in scripts_dir .glob ("*.md" ):
33
+ # Read the source files and extract the GitHub path from the Available at link at the bottom of the page
34
+ pattern = re .compile (
35
+ r"Available at:\s*\[(?P<text>.*?)\]\(https://github\.com/OSGeo/grass/tree/main/(?P<gh_path>.*?)\)"
36
+ )
37
+
38
+ for file in source_dir .glob ("*.md" ):
113
39
with file .open () as f :
114
40
for line in f :
115
- match = url_pattern .search (line )
41
+ match = pattern .search (line )
116
42
if match :
117
- toolname = match .group (1 ).strip ()
118
- scripts_tools .append (toolname )
43
+ # Extract the entire link text and the GitHub path.
44
+ text = match .group ("text" )
45
+ gh_path = match .group ("gh_path" ).strip ()
46
+
47
+ # Remove the trailing "source code" from the text to get the tool name.
48
+ toolname = re .sub (
49
+ r"\s*source\s+code\s*$" , "" , text , flags = re .IGNORECASE
50
+ ).strip ()
51
+ source_docs [toolname ] = gh_path
119
52
120
53
# Store in MkDocs extra config
121
- config ["extra" ]["scripts_tools " ] = scripts_tools
54
+ config ["extra" ]["source_docs " ] = source_docs
122
55
return config
0 commit comments