3030 "DOMParser" ,
3131]
3232FW_LINE_PREFIX = "/* FW LINE 59:b820c6d */"
33+ TRANSLATOR_EXPORT_CANDIDATES = [
34+ "detectWeb" ,
35+ "doWeb" ,
36+ "detectImport" ,
37+ "doImport" ,
38+ "detectSearch" ,
39+ "doSearch" ,
40+ "doExport" ,
41+ ]
3342
3443
3544def should_ignore (path : Path ) -> bool :
@@ -104,11 +113,41 @@ def comment_initial_json(text: str) -> tuple[str, bool]:
104113 return text , False
105114
106115
116+ def _is_function_defined (text : str , fn_name : str ) -> bool :
117+ patterns = [
118+ rf"(^|\n)\s*(?:async\s+)?function\s+{ re .escape (fn_name )} \s*\(" ,
119+ rf"(^|\n)\s*(?:var|let|const)\s+{ re .escape (fn_name )} \s*=\s*(?:async\s+)?function\b" ,
120+ rf"(^|\n)\s*(?:var|let|const)\s+{ re .escape (fn_name )} \s*=\s*(?:async\s+)?\([^)]*\)\s*=>" ,
121+ rf"(^|\n)\s*{ re .escape (fn_name )} \s*=\s*(?:async\s+)?function\b" ,
122+ ]
123+ return any (re .search (pattern , text ) for pattern in patterns )
124+
125+
107126def append_exports (text : str ) -> tuple [str , bool ]:
108- export_snippet = " \n // Export translator functions as ES module bindings for adapter \n export { detectWeb, doWeb }; \n "
109- if "export { detectWeb, doWeb }" in text :
127+ present = [ fn for fn in TRANSLATOR_EXPORT_CANDIDATES if _is_function_defined ( text , fn )]
128+ if not present :
110129 return text , False
111- return text .rstrip () + export_snippet , True
130+
131+ export_line = f"export {{ { ', ' .join (present )} }};"
132+ export_snippet = (
133+ "\n // Export translator functions as ES module bindings for adapter\n "
134+ + export_line
135+ + "\n "
136+ )
137+
138+ # Remove a previously generated trailing export block, so reruns stay idempotent
139+ generated_block_re = re .compile (
140+ r"\n?// Export translator functions as ES module bindings for adapter\n"
141+ r"export\s*\{[^}]*\};\s*\Z" ,
142+ re .MULTILINE ,
143+ )
144+ new_text = generated_block_re .sub ("" , text ).rstrip ()
145+
146+ # If an identical export already exists, avoid changing file layout
147+ if re .search (rf"(^|\n)\s*{ re .escape (export_line )} \s*(\n|\Z)" , new_text ):
148+ return new_text + "\n " , new_text != text
149+
150+ return new_text + export_snippet , True
112151
113152
114153def ensure_sandbox_import (text : str ) -> tuple [str , bool ]:
@@ -200,23 +239,25 @@ def extract_json_from_text(text: str):
200239 return None
201240
202241
203- def process_file (path : Path ) -> tuple [bool , bool , bool ]:
242+ def process_file (path : Path ) -> tuple [bool , bool , bool , bool ]:
204243 commented = False
205244 imported = False
245+ exported = False
206246
207247 text = path .read_text (encoding = "utf-8" )
208248
209249 # Delete old translators that still use the deprecated "Zotero Framework"
210250 # These are not valid esm, and are deprecated anyway: https://github.com/zotero/translators/issues/3105
211251 if has_fw_line (text ):
212252 path .unlink ()
213- return commented , imported , True
253+ return commented , imported , exported , True
214254
215255 text , commented = comment_initial_json (text )
216256
217257 text , imported = ensure_sandbox_import (text )
258+ text , exported = append_exports (text )
218259
219- if commented or imported :
260+ if commented or imported or exported :
220261 # backup original
221262 # bak = path.with_suffix(path.suffix + '.bak')
222263 # try:
@@ -226,7 +267,7 @@ def process_file(path: Path) -> tuple[bool, bool, bool]:
226267 # pass
227268 path .write_text (text , encoding = "utf-8" )
228269
229- return commented , imported , False
270+ return commented , imported , exported , False
230271
231272
232273def patch_all ():
@@ -238,22 +279,25 @@ def patch_all():
238279 total = 0
239280 commented_count = 0
240281 imported_count = 0
282+ exported_count = 0
241283 deleted_count = 0
242284 for f in js_files :
243285 total += 1
244286 try :
245- commented , imported , deleted = process_file (f )
287+ commented , imported , exported , deleted = process_file (f )
246288 if commented :
247289 commented_count += 1
248290 if imported :
249291 imported_count += 1
292+ if exported :
293+ exported_count += 1
250294 if deleted :
251295 deleted_count += 1
252296 except Exception as e :
253297 print ("Error processing" , f , e )
254298
255299 print (
256- f"Processed { total } files: deleted { deleted_count } , commented { commented_count } , sandbox imports updated { imported_count } "
300+ f"Processed { total } files: deleted { deleted_count } , commented { commented_count } , sandbox imports updated { imported_count } , exports updated { exported_count } "
257301 )
258302
259303
0 commit comments