Source code for panel.io.markdown

from __future__ import annotations

import os

from typing import IO

import bokeh.command.util

from bokeh.application.handlers.code import CodeHandler
from bokeh.command.util import (
    build_single_handler_application as _build_application,
)


[docs]def extract_code( filehandle: IO, supported_syntax: tuple[str, ...] = ('{pyodide}', 'python') ) -> str: """ Extracts Panel application code from a Markdown file. """ inblock = False block_opener = None title = None markdown = [] out = [] while True: line = filehandle.readline() if not line: # EOF break lsline = line.lstrip() if inblock: if lsline.startswith(block_opener): inblock = False else: out.append(line) elif lsline.startswith("```"): num_leading_backticks = len(lsline) - len(lsline.lstrip("`")) block_opener = '`'*num_leading_backticks syntax = line.strip()[num_leading_backticks:] if syntax in supported_syntax: if markdown: md = ''.join(markdown) markdown.clear() if any('pn.extension' in o for o in out): out.append(f"pn.pane.Markdown({md!r}).servable()\n") inblock = True else: markdown.append(line) elif line.startswith('# '): title = line[1:].lstrip() else: markdown.append(line) if markdown: md = ''.join(markdown) if any('pn.extension' in o for o in out): out.append(f"pn.pane.Markdown({md!r}).servable()\n") if title and any('template=' in o for o in out if 'pn.extension' in o): out.append(f'pn.state.template.title = {title.strip()!r}') return '\n'.join(out)
[docs]class MarkdownHandler(CodeHandler): ''' Modify Bokeh documents by creating Dashboard from a Markdown file. ''' def __init__(self, *args, **kwargs): ''' Keywords: filename (str) : a path to a Markdown (".md") file ''' if 'filename' not in kwargs: raise ValueError('Must pass a filename to Handler') filename = os.path.abspath(kwargs['filename']) with open(filename, encoding='utf-8') as f: code = extract_code(f) kwargs['source'] = code super().__init__(*args, **kwargs)
def build_single_handler_application(path, argv=None): if not os.path.isfile(path) or not path.endswith(".md"): return _build_application(path, argv) from .server import Application handler = MarkdownHandler(filename=path) if handler.failed: raise RuntimeError("Error loading %s:\n\n%s\n%s " % (path, handler.error, handler.error_detail)) application = Application(handler) return application bokeh.command.util.build_single_handler_application = build_single_handler_application