33from jinja2 import Environment
44
55
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 :
3211 return None
3312
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-
9213
9314def on_env (env : Environment , config , files ):
9415 """Enable loopcontrols extension in Jinja2"""
@@ -103,20 +24,32 @@ def on_config(config):
10324 store it in MkDocs extra config. These are used to generate
10425 the correct links to the documentation in GitHub.
10526 """
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 = {}
11132
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" ):
11339 with file .open () as f :
11440 for line in f :
115- match = url_pattern .search (line )
41+ match = pattern .search (line )
11642 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
11952
12053 # Store in MkDocs extra config
121- config ["extra" ]["scripts_tools " ] = scripts_tools
54+ config ["extra" ]["source_docs " ] = source_docs
12255 return config
0 commit comments