@@ -27,109 +27,153 @@ def _deep_merge(base, update):
2727 return merged
2828
2929
30- def main (config_path = None ):
31- """Main function for the document generator."""
32- # Get config path from arguments if not provided
30+ def _get_config_path (config_path = None ):
31+ """Get and validate the configuration file path."""
3332 if config_path is None :
3433 if len (sys .argv ) < 2 :
3534 print ("Error: Config file path is required" )
3635 print ("Usage: python -m pdfbaker <config_file_path>" )
37- return 1
36+ return None
3837 config_path = sys .argv [1 ]
39-
40- # Load main configuration
41- config_path = Path (config_path ).resolve () # Get absolute path
38+
39+ config_path = Path (config_path ).resolve ()
4240 if not config_path .exists ():
4341 print (f"Error: Configuration file not found: { config_path } " )
44- return 1
45-
42+ return None
43+
44+ return config_path
45+
46+
47+ def _load_config (config_path ):
48+ """Load configuration from a YAML file."""
4649 with open (config_path , encoding = "utf-8" ) as f :
47- config = yaml .safe_load (f )
48-
49- # Create root output directories relative to config file
50- base_dir = config_path .parent
50+ return yaml .safe_load (f )
51+
52+
53+ def _setup_output_directories (base_dir ):
54+ """Create and return build and dist directories."""
5155 build_dir = base_dir / "build"
5256 dist_dir = base_dir / "dist"
5357 os .makedirs (build_dir , exist_ok = True )
5458 os .makedirs (dist_dir , exist_ok = True )
59+ return build_dir , dist_dir
5560
56- # Allow document_paths to be absolute or relative to config file
57- documents = config .get ("documents" , [])
61+
62+ def _resolve_document_paths (base_dir , documents ):
63+ """Resolve document paths to absolute paths."""
5864 document_paths = {}
59-
65+
6066 for doc_name in documents :
61- # Check if document path is specified
6267 if isinstance (doc_name , dict ):
6368 # Format: {"name": "doc_name", "path": "/absolute/path/to/doc"}
6469 doc_path = Path (doc_name ["path" ])
6570 doc_name = doc_name ["name" ]
6671 else :
6772 # Default: document in subdirectory with same name as doc_name
6873 doc_path = base_dir / doc_name
69-
70- # Store the absolute path
74+
7175 document_paths [doc_name ] = doc_path .resolve ()
7276
73- # Process each document
74- for doc_name , doc_path in document_paths .items ():
75- if not doc_path .is_dir ():
76- print (f'Warning: Directory missing for document "{ doc_name } " at { doc_path } - skipping' )
77- continue
78-
79- bake_path = doc_path / "bake.py"
80- if not bake_path .exists ():
81- print (f'Warning: bake.py missing for document "{ doc_name } " - skipping' )
82- continue
83-
84- config_yml_path = doc_path / "config.yml"
85- if not config_yml_path .exists ():
86- print (f'Warning: config.yml missing for document "{ doc_name } " - skipping' )
87- continue
88-
89- print (f'Processing document "{ doc_name } " from { doc_path } ...' )
90-
91- # Load document-specific bake
92- doc_bake = importlib .util .spec_from_file_location (
93- f"documents.{ doc_name } .bake" ,
94- bake_path
77+ return document_paths
78+
79+
80+ def _validate_document (doc_name , doc_path ):
81+ """Validate that a document has all required files."""
82+ if not doc_path .is_dir ():
83+ print (
84+ f'Warning: Directory missing for document "{ doc_name } " '
85+ f"at { doc_path } - skipping"
9586 )
96- module = importlib .util .module_from_spec (doc_bake )
97- doc_bake .loader .exec_module (module )
98-
99- # Merge document configuration
100- with open (config_yml_path , encoding = "utf-8" ) as f :
101- doc_config = yaml .safe_load (f )
102- merged_config = _deep_merge (config , doc_config )
103-
104- # Create document-specific output directories
105- doc_build_dir = build_dir / doc_name
106- doc_dist_dir = dist_dir / doc_name
107- os .makedirs (doc_build_dir , exist_ok = True )
108- os .makedirs (doc_dist_dir , exist_ok = True )
109-
110- # Clean document-specific output directories
111- for dir_path in [doc_build_dir , doc_dist_dir ]:
112- for file in os .listdir (dir_path ):
113- file_path = dir_path / file
114- if os .path .isfile (file_path ):
115- os .remove (file_path )
116-
117- # Prepare paths for the document processor
118- paths = {
119- "doc_dir" : doc_path ,
120- "templates_dir" : doc_path / "templates" ,
121- "pages_dir" : doc_path / "pages" ,
122- "images_dir" : doc_path / "images" ,
123- "build_dir" : doc_build_dir ,
124- "dist_dir" : doc_dist_dir ,
125- }
126-
127- # Prepare Jinja environment
128- jinja_env = create_env (paths ["templates_dir" ])
129-
130- # Process the document
131- module .process_document (paths , merged_config , jinja_env )
132-
87+ return False
88+
89+ bake_path = doc_path / "bake.py"
90+ if not bake_path .exists ():
91+ print (f'Warning: bake.py missing for document "{ doc_name } " - skipping' )
92+ return False
93+
94+ config_yml_path = doc_path / "config.yml"
95+ if not config_yml_path .exists ():
96+ print (f'Warning: config.yml missing for document "{ doc_name } " - skipping' )
97+ return False
98+
99+ return bake_path , config_yml_path
100+
101+
102+ def _load_document_bake_module (doc_name , bake_path ):
103+ """Load the document's bake.py module."""
104+ doc_bake = importlib .util .spec_from_file_location (
105+ f"documents.{ doc_name } .bake" , bake_path
106+ )
107+ module = importlib .util .module_from_spec (doc_bake )
108+ doc_bake .loader .exec_module (module )
109+ return module
110+
111+
112+ def _setup_document_directories (build_dir , dist_dir , doc_name ):
113+ """Set up and clean document-specific build and dist directories."""
114+ doc_build_dir = build_dir / doc_name
115+ doc_dist_dir = dist_dir / doc_name
116+ os .makedirs (doc_build_dir , exist_ok = True )
117+ os .makedirs (doc_dist_dir , exist_ok = True )
118+
119+ # Clean document-specific output directories
120+ for dir_path in [doc_build_dir , doc_dist_dir ]:
121+ for file in os .listdir (dir_path ):
122+ file_path = dir_path / file
123+ if os .path .isfile (file_path ):
124+ os .remove (file_path )
125+
126+ return doc_build_dir , doc_dist_dir
127+
128+
129+ def _process_document (doc_name , doc_path , config , build_dir , dist_dir ):
130+ """Process an individual document."""
131+ validation_result = _validate_document (doc_name , doc_path )
132+ if not validation_result :
133+ return
134+
135+ print (f'Processing document "{ doc_name } " from { doc_path } ...' )
136+ bake_path , config_yml_path = validation_result
137+ bake_module = _load_document_bake_module (doc_name , bake_path )
138+ with open (config_yml_path , encoding = "utf-8" ) as f :
139+ doc_config = yaml .safe_load (f )
140+
141+ doc_build_dir , doc_dist_dir = _setup_document_directories (
142+ build_dir , dist_dir , doc_name
143+ )
144+ paths = {
145+ "doc_dir" : doc_path ,
146+ "templates_dir" : doc_path / "templates" ,
147+ "pages_dir" : doc_path / "pages" ,
148+ "images_dir" : doc_path / "images" ,
149+ "build_dir" : doc_build_dir ,
150+ "dist_dir" : doc_dist_dir ,
151+ }
152+
153+ bake_module .process_document (
154+ paths = paths ,
155+ config = _deep_merge (config , doc_config ),
156+ jinja_env = create_env (paths ["templates_dir" ]),
157+ )
158+
159+
160+ def main (config_path = None ):
161+ """Main function for the document generator."""
162+ config_path = _get_config_path (config_path )
163+ if config_path is None :
164+ return 1
165+
166+ config = _load_config (config_path )
167+
168+ base_dir = config_path .parent
169+ build_dir , dist_dir = _setup_output_directories (base_dir )
170+
171+ documents = config .get ("documents" , [])
172+ document_paths = _resolve_document_paths (base_dir , documents )
173+
174+ for doc_name , doc_path in document_paths .items ():
175+ _process_document (doc_name , doc_path , config , build_dir , dist_dir )
176+
133177 return 0
134178
135179
0 commit comments