chiark / gitweb /
documentation/*: add a SEARCH_FILENAME_PREFIX option.
authorVladimír Vondruš <mosra@centrum.cz>
Mon, 3 Jan 2022 19:13:20 +0000 (20:13 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Mon, 3 Jan 2022 19:13:20 +0000 (20:13 +0100)
Allows to override the search data filename, which is useful when both
Python and C++ documentation shares the same directory. Otherwise both
would use the same search data filename and overwrite each other's data.

14 files changed:
doc/documentation/doxygen.rst
doc/documentation/python.rst
documentation/_search.py
documentation/doxygen.py
documentation/python.py
documentation/templates/doxygen/base.html
documentation/templates/python/base.html
documentation/test_doxygen/search/Doxyfile
documentation/test_doxygen/test_doxyfile.py
documentation/test_doxygen/test_layout.py
documentation/test_doxygen/test_search.py
documentation/test_doxygen/test_undocumented.py
documentation/test_python/test_layout.py
documentation/test_python/test_search.py

index d89d38980ef819540f107ec8cd173c9a63c53303..6366f8bd48de2f9913af3428d883d3efc4e5bd76 100644 (file)
@@ -385,6 +385,11 @@ Variable                            Description
                                     bandwidth and initial processing time. If
                                     not set, :py:`False` is used. See
                                     `Search options`_ for more information.
+:py:`SEARCH_FILENAME_PREFIX: str`   Search data filename prefix. Useful to
+                                    prevent file conflicts if both C++ and
+                                    Python documentation shares the same
+                                    directory. If not set, ``searchdata`` is
+                                    used.
 :py:`SEARCH_HELP: str`              HTML code to display as help text on empty
                                     search popup. If not set, a default message
                                     is used. Has effect only if
@@ -473,6 +478,7 @@ these are not expected to be excessively large.
     :ini:`M_MATH_CACHE_FILE`            :py:`M_MATH_CACHE_FILE`
     :ini:`M_SEARCH_DISABLED`            :py:`SEARCH_DISABLED`
     :ini:`M_SEARCH_DOWNLOAD_BINARY`     :py:`SEARCH_DOWNLOAD_BINARY`
+    :ini:`M_SEARCH_FILENAME_PREFIX`     :py:`SEARCH_FILENAME_PREFIX`
     :ini:`M_SEARCH_HELP`                :py:`SEARCH_HELP`
     :ini:`M_SEARCH_BASE_URL`            :py:`SEARCH_BASE_URL`
     :ini:`M_SEARCH_EXTERNAL_URL`        :py:`SEARCH_EXTERNAL_URL`
index 50c5ff2a7bd718dbadeb62f69e2c14a117790ee6..3f972ee20c24db1ce4821f193b072cbfed3ba7a4 100644 (file)
@@ -239,6 +239,11 @@ Variable                            Description
                                     bandwidth and initial processing time. If
                                     not set, :py:`False` is used. See `Search options`_
                                     for more information.
+:py:`SEARCH_FILENAME_PREFIX: str`   Search data filename prefix. Useful to
+                                    prevent file conflicts if both C++ and
+                                    Python documentation shares the same
+                                    directory. If not set, ``searchdata`` is
+                                    used.
 :py:`SEARCH_HELP: str`              :abbr:`reST <reStructuredText>` markup to
                                     display as help text on empty search popup.
                                     If not set, a default message is used. Has
index a5db63c051aab61810ca4a512fa923095b5db943..9c0297aacc19008c7690bbcdf744e256893392b0 100644 (file)
@@ -34,8 +34,8 @@ from typing import List, Tuple
 # Version 0 was without the type map
 searchdata_format_version = 1
 search_filename = f'search-v{searchdata_format_version}.js'
-searchdata_filename = f'searchdata-v{searchdata_format_version}.bin'
-searchdata_filename_b85 = f'searchdata-v{searchdata_format_version}.js'
+searchdata_filename = f'{{search_filename_prefix}}-v{searchdata_format_version}.bin'
+searchdata_filename_b85 = f'{{search_filename_prefix}}-v{searchdata_format_version}.js'
 
 class CssClass(enum.Enum):
     DEFAULT = 0
index c38cad96ec8c56f29de27ceac158cb303f958534..822dca78305534d4b86ce7bb92ce3baa4b55b953 100755 (executable)
@@ -125,6 +125,7 @@ default_config = {
 
     'SEARCH_DISABLED': False,
     'SEARCH_DOWNLOAD_BINARY': False,
+    'SEARCH_FILENAME_PREFIX': 'searchdata',
     'SEARCH_HELP':
 """<p class="m-noindent">Search for symbols, directories, files, pages or
 modules. You can omit any prefix from the symbol or file path; adding a
@@ -3508,6 +3509,7 @@ def parse_doxyfile(state: State, doxyfile, values = None):
 
         ('M_SEARCH_DISABLED', 'SEARCH_DISABLED', bool),
         ('M_SEARCH_DOWNLOAD_BINARY', 'SEARCH_DOWNLOAD_BINARY', bool),
+        ('M_SEARCH_FILENAME_PREFIX', 'SEARCH_FILENAME_PREFIX', str),
         ('M_SEARCH_HELP', 'SEARCH_HELP', str),
         ('M_SEARCH_BASE_URL', 'SEARCH_BASE_URL', str),
         ('M_SEARCH_EXTERNAL_URL', 'SEARCH_EXTERNAL_URL', str),
@@ -3768,10 +3770,10 @@ def run(state: State, *, templates=default_templates, wildcard=default_wildcard,
         data = build_search_data(state, add_lookahead_barriers=search_add_lookahead_barriers, merge_subtrees=search_merge_subtrees, merge_prefixes=search_merge_prefixes)
 
         if state.config['SEARCH_DOWNLOAD_BINARY']:
-            with open(os.path.join(html_output, searchdata_filename), 'wb') as f:
+            with open(os.path.join(html_output, searchdata_filename.format(search_filename_prefix=state.config['SEARCH_FILENAME_PREFIX'])), 'wb') as f:
                 f.write(data)
         else:
-            with open(os.path.join(html_output, searchdata_filename_b85), 'wb') as f:
+            with open(os.path.join(html_output, searchdata_filename_b85.format(search_filename_prefix=state.config['SEARCH_FILENAME_PREFIX'])), 'wb') as f:
                 f.write(base85encode_search_data(data))
 
         # OpenSearch metadata, in case we have the base URL
index c3b059e866df6484888fae50ffb4198247871bcb..8ae8347fe77ed259e8f1e11059f3542ff3fd2c27 100755 (executable)
@@ -171,6 +171,7 @@ default_config = {
 
     'SEARCH_DISABLED': False,
     'SEARCH_DOWNLOAD_BINARY': False,
+    'SEARCH_FILENAME_PREFIX': 'searchdata',
     'SEARCH_HELP': """.. raw:: html
 
     <p class="m-noindent">Search for modules, classes, functions and other
@@ -2686,10 +2687,10 @@ def run(basedir, config, *, templates=default_templates, search_add_lookahead_ba
         # TODO: any chance we could write the file *before* it gets ever passed
         # to URL formatters so we can add cache buster hashes to its URL?
         if state.config['SEARCH_DOWNLOAD_BINARY']:
-            with open(os.path.join(config['OUTPUT'], config['URL_FORMATTER'](EntryType.STATIC, [os.path.join(config['OUTPUT'], state.config['SEARCH_DOWNLOAD_BINARY'] if isinstance(state.config['SEARCH_DOWNLOAD_BINARY'], str) else searchdata_filename)])[0]), 'wb') as f:
+            with open(os.path.join(config['OUTPUT'], config['URL_FORMATTER'](EntryType.STATIC, [os.path.join(config['OUTPUT'], state.config['SEARCH_DOWNLOAD_BINARY'] if isinstance(state.config['SEARCH_DOWNLOAD_BINARY'], str) else searchdata_filename.format(search_filename_prefix=state.config['SEARCH_FILENAME_PREFIX']))])[0]), 'wb') as f:
                 f.write(data)
         else:
-            with open(os.path.join(config['OUTPUT'], config['URL_FORMATTER'](EntryType.STATIC, [os.path.join(config['OUTPUT'], searchdata_filename_b85)])[0]), 'wb') as f:
+            with open(os.path.join(config['OUTPUT'], config['URL_FORMATTER'](EntryType.STATIC, [os.path.join(config['OUTPUT'], searchdata_filename_b85.format(search_filename_prefix=state.config['SEARCH_FILENAME_PREFIX']))])[0]), 'wb') as f:
                 f.write(base85encode_search_data(data))
 
         # OpenSearch metadata, in case we have the base URL
index f212976493cc71e6f23550fd8238c69747b6708d..55a15f82896970b620635f14d5f994f997f25977 100644 (file)
 <script src="search-v{{ SEARCHDATA_FORMAT_VERSION }}.js"></script>
 {% if SEARCH_DOWNLOAD_BINARY %}
 <script>
-  Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + 'searchdata-v{{ SEARCHDATA_FORMAT_VERSION }}.bin');
+  Search.download(window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + '{{ SEARCH_FILENAME_PREFIX }}-v{{ SEARCHDATA_FORMAT_VERSION }}.bin');
 </script>
 {% else %}
-<script src="searchdata-v{{ SEARCHDATA_FORMAT_VERSION }}.js" async="async"></script>
+<script src="{{ SEARCH_FILENAME_PREFIX }}-v{{ SEARCHDATA_FORMAT_VERSION }}.js" async="async"></script>
 {% endif %}
 {% endif %}
 {% if FINE_PRINT %}
index 797186980b6ba37515e3ee776f78e209d3f5fe3d..3de656b3fbf785916a1dff09b2d56662b6e1f794 100644 (file)
 <script src="{{ 'search.js'|format_url|e }}"></script>
 {% if SEARCH_DOWNLOAD_BINARY %}
 <script>
-  Search.download({% if SEARCH_DOWNLOAD_BINARY is string %}'{{ SEARCH_DOWNLOAD_BINARY.format(SEARCHDATA_FORMAT_VERSION)|format_url|e }}'{% else %}window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + 'searchdata-v{{ SEARCHDATA_FORMAT_VERSION }}.bin'{% endif %});
+  Search.download({% if SEARCH_DOWNLOAD_BINARY is string %}'{{ SEARCH_DOWNLOAD_BINARY.format(SEARCHDATA_FORMAT_VERSION)|format_url|e }}'{% else %}window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/') + 1) + '{{ SEARCH_FILENAME_PREFIX }}-v{{ SEARCHDATA_FORMAT_VERSION }}.bin'{% endif %});
 </script>
 {% else %}
-<script src="{{ 'searchdata-v{}.js'.format(SEARCHDATA_FORMAT_VERSION)|format_url|e }}" async="async"></script>
+<script src="{{ '{}-v{}.js'.format(SEARCH_FILENAME_PREFIX, SEARCHDATA_FORMAT_VERSION)|format_url|e }}" async="async"></script>
 {% endif %}
 {% endif %}
 {% if FINE_PRINT %}
index 7d6b64e7dbb434ce2314196d75e148686e5348c1..783fdd082b86274d1b25588b03d868306dee6ab6 100644 (file)
@@ -21,3 +21,4 @@ ALIASES                 = \
 ##! M_LINKS_NAVBAR1     =
 ##! M_LINKS_NAVBAR2     =
 ##! M_SEARCH_DOWNLOAD_BINARY = YES
+##! M_SEARCH_FILENAME_PREFIX = secretblob
index 252798b643e929f429d2325933e3446329416476..a191420cc90375bc6fa53191e78bdb8c65ed1f8f 100644 (file)
@@ -76,6 +76,7 @@ class Doxyfile(unittest.TestCase):
 
         'SEARCH_DISABLED': False,
         'SEARCH_DOWNLOAD_BINARY': False,
+        'SEARCH_FILENAME_PREFIX': 'searchdata',
         'SEARCH_BASE_URL': None,
         'SEARCH_EXTERNAL_URL': None,
         'SEARCH_HELP':
index 3170c86551e1a76a3a22d9f223467c22b833a56d..92ce94e75ada63f6e4067d05ebf43293c7926d0e 100644 (file)
@@ -34,7 +34,7 @@ class Layout(BaseTestCase):
         self.assertEqual(*self.actual_expected_contents('pages.html'))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'm-dark+documentation.compiled.css')))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'html', search_filename)))
-        self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename_b85)))
+        self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename_b85.format(search_filename_prefix='searchdata'))))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'html', 'favicon-light.png')))
 
 class GeneratedDoxyfile(BaseTestCase):
@@ -85,7 +85,7 @@ class SearchBinary(BaseTestCase):
     def test(self):
         self.run_doxygen(wildcard='indexpage.xml')
         self.assertEqual(*self.actual_expected_contents('index.html'))
-        self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename)))
+        self.assertTrue(os.path.exists(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='searchdata'))))
 
 class SearchOpensearch(BaseTestCase):
     def test(self):
index 73d7d963bba082a1cc26930b3f954576c0995be1..267ce5351ee6a8f31e9a5addec9545139155680e 100755 (executable)
@@ -37,7 +37,7 @@ class Search(IntegrationTestCase):
     def test(self):
         self.run_doxygen(index_pages=[], wildcard='*.xml')
 
-        with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
+        with open(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='secretblob')), 'rb') as f:
             serialized = f.read()
             search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
         #print(search_data_pretty)
@@ -229,7 +229,7 @@ class LongSuffixLength(IntegrationTestCase):
     def test(self):
         self.run_doxygen(index_pages=[], wildcard='*.xml')
 
-        with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
+        with open(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f:
             serialized = f.read()
             search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
         #print(search_data_pretty)
index 2252a9af91836aa08f8a9d47b2c0454efa1e9ef8..17e89448cd61c79baaca6460e9e230293f7b8efb 100644 (file)
@@ -51,7 +51,7 @@ class Undocumented(IntegrationTestCase):
         # Test we have all symbols in search data. It's enough to assert the
         # count, it equal to symbol count in the header file
         # TODO: reuse the search data deserialization API once done
-        with open(os.path.join(self.path, 'html', searchdata_filename), 'rb') as f:
+        with open(os.path.join(self.path, 'html', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f:
             serialized = f.read()
             magic, version, symbol_count, map_offset, type_map_offset = search_data_header_struct.unpack_from(serialized)
             self.assertEqual(symbol_count, 44)
index ac23f85c4713bdbf74f3764498a33370fcbd84bf..a02a38a13a6626c9fad77785375a5436b1b4bb05 100644 (file)
@@ -60,7 +60,7 @@ class Layout(BaseTestCase):
         self.assertTrue(os.path.exists(os.path.join(self.path, 'output/m-dark+documentation.compiled.css')))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'output/favicon-light.png')))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'output/search-v{}.js'.format(searchdata_format_version))))
-        self.assertTrue(os.path.exists(os.path.join(self.path, 'output', searchdata_filename_b85)))
+        self.assertTrue(os.path.exists(os.path.join(self.path, 'output', searchdata_filename_b85.format(search_filename_prefix='searchdata'))))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'output/sitemap.xml')))
 
 class SearchBinary(BaseTestCase):
@@ -71,7 +71,7 @@ class SearchBinary(BaseTestCase):
         })
         self.assertEqual(*self.actual_expected_contents('index.html'))
         self.assertTrue(os.path.exists(os.path.join(self.path, 'output', 'search-v{}.js'.format(searchdata_format_version))))
-        self.assertTrue(os.path.exists(os.path.join(self.path, 'output', searchdata_filename)))
+        self.assertTrue(os.path.exists(os.path.join(self.path, 'output', searchdata_filename.format(search_filename_prefix='searchdata'))))
 
 class SearchOpenSearch(BaseTestCase):
     def test(self):
index 22c1324d3765acaa9a1d9174b9622f635191832c..fe43d9e1445f60d8c8e3b3d981966a06c5d1930d 100644 (file)
@@ -36,10 +36,11 @@ class Search(BaseInspectTestCase):
         self.run_python({
             'SEARCH_DISABLED': False,
             'SEARCH_DOWNLOAD_BINARY': True,
+            'SEARCH_FILENAME_PREFIX': 'secretblob',
             'PYBIND11_COMPATIBILITY': True
         })
 
-        with open(os.path.join(self.path, 'output', searchdata_filename), 'rb') as f:
+        with open(os.path.join(self.path, 'output', searchdata_filename.format(search_filename_prefix='secretblob')), 'rb') as f:
             serialized = f.read()
             search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
         #print(search_data_pretty)
@@ -192,7 +193,7 @@ class LongSuffixLength(BaseInspectTestCase):
             'PYBIND11_COMPATIBILITY': True
         })
 
-        with open(os.path.join(self.path, 'output', searchdata_filename), 'rb') as f:
+        with open(os.path.join(self.path, 'output', searchdata_filename.format(search_filename_prefix='searchdata')), 'rb') as f:
             serialized = f.read()
             search_data_pretty = pretty_print(serialized, entryTypeClass=EntryType)[0]
         #print(search_data_pretty)