1212
1313from .config import PDFBakerConfiguration , deep_merge
1414from .document import PDFBakerDocument
15- from .errors import ConfigurationError
15+ from .errors import ConfigurationError , DocumentNotFoundError
1616from .logging import LoggingMixin , setup_logging
1717
1818__all__ = ["PDFBaker" , "PDFBakerOptions" ]
@@ -59,6 +59,7 @@ def __init__(
5959 ) -> None :
6060 """Initialize baker configuration (needs documents)."""
6161 self .baker = baker
62+ self .name = config_file .name
6263 self .baker .log_debug_section ("Loading main configuration: %s" , config_file )
6364 super ().__init__ (base_config , config_file )
6465 self .baker .log_trace (self .pretty ())
@@ -67,10 +68,12 @@ def __init__(
6768 'Key "documents" missing - is this the main configuration file?'
6869 )
6970 self .build_dir = self ["directories" ]["build" ]
70- self .documents = [
71- self .resolve_path (doc_spec , directory = self ["directories" ]["documents" ])
72- for doc_spec in self ["documents" ]
73- ]
71+ self .documents = []
72+ for doc_spec in self ["documents" ]:
73+ doc_path = self .resolve_path (
74+ doc_spec , directory = self ["directories" ]["documents" ]
75+ )
76+ self .documents .append ({"name" : doc_path .name , "path" : doc_path })
7477
7578 def __init__ (
7679 self ,
@@ -99,22 +102,61 @@ def __init__(
99102 config_file = config_file ,
100103 )
101104
102- def bake (self ) -> None :
103- """Create PDFs for all documents.
105+ def _get_documents_to_process (
106+ self , selected_document_names : tuple [str , ...] | None = None
107+ ) -> list [Path ]:
108+ """Get the document paths to process based on optional filtering.
109+
110+ Args:
111+ document_names: Optional tuple of document names to process
112+
113+ Returns:
114+ List of document paths to process
115+ """
116+ if not selected_document_names :
117+ return self .config .documents
118+
119+ available_doc_names = [doc ["name" ] for doc in self .config .documents ]
120+ missing_docs = [
121+ name for name in selected_document_names if name not in available_doc_names
122+ ]
123+ if missing_docs :
124+ self .log_info (
125+ f"Documents in { self .config .name } : %s" ,
126+ ", " .join (f'"{ name } "' for name in available_doc_names ),
127+ )
128+ raise DocumentNotFoundError (
129+ f"{ 'Document' if len (missing_docs ) == 1 else 'Documents' } not found in "
130+ f"configuration: { ', ' .join (f'"{ name } "' for name in missing_docs )} ."
131+ )
132+
133+ return [
134+ doc
135+ for doc in self .config .documents
136+ if doc ["name" ] in selected_document_names
137+ ]
138+
139+ def bake (self , document_names : tuple [str , ...] | None = None ) -> bool :
140+ """Create PDFs for all documents or only the specified ones.
141+
142+ Args:
143+ document_names: Optional tuple of document names to process
104144
105145 Returns:
106146 bool: True if all documents were processed successfully, False if any failed
107147 """
108148 pdfs_created : list [Path ] = []
109149 failed_docs : list [tuple [str , str ]] = []
110150
151+ documents = self ._get_documents_to_process (document_names )
152+
111153 self .log_debug_subsection ("Documents to process:" )
112- self .log_debug (self . config . documents )
113- for doc_config in self . config . documents :
154+ self .log_debug (documents )
155+ for doc_config in documents :
114156 doc = PDFBakerDocument (
115157 baker = self ,
116158 base_config = self .config ,
117- config_path = doc_config ,
159+ config_path = doc_config [ "path" ] ,
118160 )
119161 pdf_files , error_message = doc .process_document ()
120162 if error_message :
0 commit comments