Selaa lähdekoodia

build search index on startup

Falko Schindler 1 vuosi sitten
vanhempi
säilyke
4cbd9e6d98

+ 1 - 0
main.py

@@ -24,6 +24,7 @@ app.add_static_file(local_file=svg.PATH / 'logo.png', url_path='/logo.png')
 app.add_static_file(local_file=svg.PATH / 'logo_square.png', url_path='/logo_square.png')
 
 documentation.content.generate()
+documentation.build_search_index()
 
 
 @app.post('/dark_mode')

+ 2 - 0
website/documentation/__init__.py

@@ -1,11 +1,13 @@
 from . import content, registry
 from .intro import create_intro
 from .rendering import render_page
+from .search import build_search_index
 from .windows import bash_window, browser_window, python_window
 
 __all__ = [
     'bash_window',
     'browser_window',
+    'build_search_index',
     'content',
     'create_intro',
     'python_window',

+ 14 - 12
website/documentation/model.py

@@ -2,12 +2,10 @@ from __future__ import annotations
 
 import abc
 from dataclasses import dataclass
-from typing import Callable, Iterator, List, Optional, Union, overload
-
-import docutils.core
+from typing import Callable, Iterator, List, Literal, Optional, Union, overload
 
 from nicegui.dataclasses import KWONLY_SLOTS
-from nicegui.elements.markdown import apply_tailwind, remove_indentation
+from nicegui.elements.markdown import remove_indentation
 
 from . import registry
 
@@ -16,6 +14,7 @@ from . import registry
 class DocumentationPart:
     title: Optional[str] = None
     description: Optional[str] = None
+    description_format: Literal['md', 'rst'] = 'md'
     link: Optional[str] = None
     ui: Optional[Callable] = None
     demo: Optional[Callable] = None
@@ -64,18 +63,21 @@ class Documentation(abc.ABC):
         """Add a demo section to the documentation."""
         if len(args) == 2:
             title, description = args
-        elif isinstance(args[0], type):
-            title, description = args[0].__init__.__doc__.split('\n', 1)  # type: ignore
-        elif callable(args[0]):
-            title, description = args[0].__doc__.split('\n', 1)
+            is_markdown = True
         else:
-            raise ValueError('Invalid arguments')
+            doc = args[0].__init__.__doc__ if isinstance(args[0], type) else args[0].__doc__  # type: ignore
+            title, description = doc.split('\n', 1)
+            is_markdown = False
 
-        description = remove_indentation(description).replace('param ', '')
-        html = apply_tailwind(docutils.core.publish_parts(description, writer_name='html5_polyglot')['html_body'])
+        description = remove_indentation(description)
 
         def decorator(function: Callable) -> Callable:
-            self._content.append(DocumentationPart(title=title, description=html, demo=function))
+            self._content.append(DocumentationPart(
+                title=title,
+                description=description,
+                description_format='md' if is_markdown else 'rst',
+                demo=function,
+            ))
             return function
         return decorator
 

+ 10 - 1
website/documentation/rendering.py

@@ -1,4 +1,7 @@
+import docutils.core
+
 from nicegui import ui
+from nicegui.elements.markdown import apply_tailwind
 
 from ..header import add_head_html, add_header
 from ..style import section_heading, subheading
@@ -39,7 +42,13 @@ def render_page(documentation: Documentation, *, is_main: bool = False) -> None:
                 link = part.link if part.link != documentation.route else None
                 subheading(part.title, make_menu_entry=not is_main, link=link)
             if part.description:
-                ui.markdown(part.description)
+                if part.description_format == 'rst':
+                    description = part.description.replace('param ', '')
+                    html = docutils.core.publish_parts(description, writer_name='html5_polyglot')['html_body']
+                    html = apply_tailwind(html)
+                    ui.html(html)
+                else:
+                    ui.markdown(part.description)
             if part.ui:
                 part.ui()
             if part.demo:

+ 20 - 0
website/documentation/search.py

@@ -0,0 +1,20 @@
+import json
+from pathlib import Path
+
+from . import registry
+
+PATH = Path(__file__).parent.parent / 'static' / 'search_index.json'
+
+
+def build_search_index() -> None:
+    """Build search index."""
+    index = [
+        {
+            'title': f'{documentation.title.replace("*", "")}: {part.title}',
+            'content': part.description,
+            'url': f'{documentation.route}#{part.link_target}',
+        }
+        for documentation in registry.registry.values()
+        for part in documentation
+    ]
+    PATH.write_text(json.dumps(index, indent=2))