diff --git a/skoolkit/skool2html.py b/skoolkit/skool2html.py index 492294af..15f4630e 100644 --- a/skoolkit/skool2html.py +++ b/skoolkit/skool2html.py @@ -1,4 +1,4 @@ -# Copyright 2008-2022 Richard Dymond (rjdymond@gmail.com) +# Copyright 2008-2022, 2024 Richard Dymond (rjdymond@gmail.com) # # This file is part of SkoolKit. # @@ -250,12 +250,13 @@ def write_disassembly(html_writer, files, search_dir, extra_search_dirs, pages, # Copy resources named in the [Resources] section resources = html_writer.ref_parser.get_dictionary('Resources') search_dirs = _get_search_dirs(extra_search_dirs, search_dir) - for f, dest_dir in resources.items(): + for f, dest in resources.items(): fnames = [] for d in search_dirs: fnames.extend(glob.glob(os.path.join(d, f), recursive=True)) if not fnames: raise SkoolKitError('Cannot copy resource "{}": file not found'.format(normpath(f))) + dest_dir = html_writer.format_path(dest) for fname in fnames: if os.path.isfile(fname): copy_resource(fname, odir, dest_dir) diff --git a/skoolkit/skoolhtml.py b/skoolkit/skoolhtml.py index 698bcd8f..c6d82248 100644 --- a/skoolkit/skoolhtml.py +++ b/skoolkit/skoolhtml.py @@ -194,7 +194,7 @@ def __init__(self, skool_parser, ref_parser, file_info=None, code_id=MAIN_CODE_I self.titles.setdefault(map_name, map_name) self._expand_values(self.paths) - self.image_paths = {k: v for k, v in self.paths.items() if k.endswith('ImagePath')} + self.all_paths = {k: v for k, v in self.paths.items() if k.endswith('Path')} self.asm_fname_template = self.paths['CodeFiles'] self.udg_fname_template = self.paths['UDGFilename'] @@ -1006,18 +1006,18 @@ def _image_path(self, fname, path_id): """ if fname: fname = self.image_writer.image_fname(fname) - expanded = self._expand_image_path(fname) + expanded = self.format_path(fname) if expanded != fname or fname.startswith('/'): return expanded.lstrip('/') if path_id in self.paths: - return join(self._expand_image_path(self.paths[path_id]), fname) + return join(self.format_path(self.paths[path_id]), fname) raise SkoolKitError("Unknown path ID '{0}' for image file '{1}'".format(path_id, fname)) - def _expand_image_path(self, path): + def format_path(self, path): orig_path = prev_path = path while True: try: - path = path.format(**self.image_paths) + path = path.format(**self.all_paths) except KeyError: break if path in (prev_path, orig_path): diff --git a/sphinx/source/changelog.rst b/sphinx/source/changelog.rst index 01182895..bb59688b 100644 --- a/sphinx/source/changelog.rst +++ b/sphinx/source/changelog.rst @@ -12,6 +12,8 @@ Changelog * Added the ``Opcodes`` configuration parameter to :ref:`sna2skool.py ` (for specifying additional opcode sequences to disassemble) +* Added support for path ID replacement fields in the ``destDir`` parameter of + items in the :ref:`resources` section * Fixed the bug that prevents the ``--reg`` option of :ref:`trace.py` from accepting hexadecimal values prefixed by '0x' diff --git a/sphinx/source/ref-files.rst b/sphinx/source/ref-files.rst index 4aae8aba..a06ceb0a 100644 --- a/sphinx/source/ref-files.rst +++ b/sphinx/source/ref-files.rst @@ -909,6 +909,10 @@ which are expanded as follows: sequence of characters (e.g. ``abcde``) or a range (e.g. ``a-e``) * ``[!seq]`` - matches any character not in ``seq`` +If ``destDir`` contains a path ID replacement field (e.g. ``{AudioPath}``), the +corresponding parameter value from the :ref:`Paths` section will be +substituted. + If your disassembly requires pre-built images or other resources that SkoolKit does not build, listing them in this section ensures that they will be copied into place whenever the disassembly is built. @@ -916,6 +920,9 @@ into place whenever the disassembly is built. +---------+-------------------------------------------------------------------+ | Version | Changes | +=========+===================================================================+ +| 9.3 | Added support for path ID replacement fields in the ``destDir`` | +| | parameter | ++---------+-------------------------------------------------------------------+ | 8.0 | Added support for the ``**`` pattern | +---------+-------------------------------------------------------------------+ | 6.3 | Added support for pathname pattern expansion using wildcard | diff --git a/tests/test_skool2html.py b/tests/test_skool2html.py index 7b6b80fe..5488a720 100644 --- a/tests/test_skool2html.py +++ b/tests/test_skool2html.py @@ -800,6 +800,57 @@ def test_resources_are_copied(self): self.assertTrue(os.path.isfile(os.path.join(game_dir, dest_dir, resource2))) self.assertTrue(os.path.isfile(os.path.join(game_dir, dest_dir, resource3))) + @patch.object(skool2html, 'get_object', Mock(return_value=TestHtmlWriter)) + @patch.object(skool2html, 'SkoolParser', MockSkoolParser) + def test_resources_using_path_id_replacement_fields(self): + resource_dir = self.make_directory() + self.write_bin_file(path=f'{resource_dir}/sound.wav') + self.write_bin_file(path=f'{resource_dir}/asm.html') + self.write_bin_file(path=f'{resource_dir}/font.png') + self.write_bin_file(path=f'{resource_dir}/font.ttf') + self.write_bin_file(path=f'{resource_dir}/logo.png') + self.write_bin_file(path=f'{resource_dir}/game.js') + self.write_bin_file(path=f'{resource_dir}/scr.png') + self.write_bin_file(path=f'{resource_dir}/style.css') + self.write_bin_file(path=f'{resource_dir}/udg.png') + ref = """ + [Paths] + AudioPath=a + CodePath=b + FontImagePath=c + FontPath=d + ImagePath=e + JavaScriptPath=f + ScreenshotImagePath=g + StyleSheetPath=h + UDGImagePath=i + + [Resources] + sound.wav={AudioPath}/1 + asm.html={CodePath}/2 + font.png={FontImagePath}/3 + font.ttf={FontPath}/4 + logo.png={ImagePath}/5 + game.js={JavaScriptPath}/6 + scr.png={ScreenshotImagePath}/7 + style.css={StyleSheetPath}/8 + udg.png={UDGImagePath}/9 + """ + reffile = self._write_ref_file(ref) + skoolfile = self.write_text_file(path='{}.skool'.format(reffile[:-4])) + output, error = self.run_skool2html('-d {} -S {} {}'.format(self.odir, resource_dir, skoolfile)) + self.assertEqual(error, '') + game_dir = os.path.join(self.odir, reffile[:-4]) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'a', '1', 'sound.wav'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'b', '2', 'asm.html'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'c', '3', 'font.png'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'd', '4', 'font.ttf'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'e', '5', 'logo.png'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'f', '6', 'game.js'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'g', '7', 'scr.png'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'h', '8', 'style.css'))) + self.assertTrue(os.path.isfile(os.path.join(game_dir, 'i', '9', 'udg.png'))) + @patch.object(skool2html, 'get_object', Mock(return_value=TestHtmlWriter)) @patch.object(skool2html, 'SkoolParser', MockSkoolParser) def test_resources_using_pathname_expansion(self):