(integrations)= # Integrations ```{rst-class} lead Build application-level Markdown pipelines with a reusable Wenmode instance, safe user-content defaults, generated heading IDs, table-of-contents output, AST export, and streaming previews. ``` --- Use this page when you are wiring Wenmode into an application rather than trying one API call. The examples keep parser setup, rendering policy, and post-processing in one place so the behavior is easy to test. ## Reuse one configured instance Create a small service object around the rule set your product supports. A `Wenmode` instance can be reused across calls; render state is created per render operation. ```python from wenmode import Wenmode from wenmode.presets import github class MarkdownService: def __init__(self, wenmode: Wenmode | None = None) -> None: self.wenmode = wenmode if wenmode is not None else Wenmode(github) def render_comment(self, text: str) -> str: return self.wenmode.render(text) service = MarkdownService() text = ''' - [x] ship docs Visit https://example.com ''' html = service.render_comment(text) assert '' in html assert 'https://example.com' in html ``` ## Render untrusted user content For comments, profile fields, forum posts, and other user-authored Markdown, start with the default HTML renderer. It escapes raw HTML and removes unsafe link targets. ```python from wenmode import Wenmode from wenmode.presets import github wenmode = Wenmode(github) text = ''' Hello . [bad](javascript:alert(1)) ''' html = wenmode.render(text) assert '<script>alert(1)</script>' in html assert 'bad' in html assert 'javascript:alert' not in html ``` If your application also wants raw HTML syntax to stay as plain text in the AST, remove the raw HTML parser rules as shown in {ref}`recipes`. ## Publish documentation pages Documentation sites often need the rendered body, a table of contents, and a machine-readable AST for search or indexing. Parse once, then run tree transforms before rendering. ```python import json from wenmode import HTMLRenderer, Wenmode from wenmode.headings import Slugger, add_heading_ids from wenmode.toc import collect_toc, render_toc_html class RenderedPage: def __init__(self, html: str, toc_html: str, ast_json: str) -> None: self.html = html self.toc_html = toc_html self.ast_json = ast_json def render_page(source: str) -> RenderedPage: root = Wenmode().parse(source) add_heading_ids(root, slugger=Slugger(), min_depth=2) toc = collect_toc(root, min_depth=2, max_depth=3) toc_html = render_toc_html(toc) body_html = HTMLRenderer().render(root) return RenderedPage( html=toc_html + body_html, toc_html=toc_html, ast_json=json.dumps(root.to_ast(), ensure_ascii=False), ) text = ''' # Guide ## Install Run **wenmode**. ''' page = render_page(text) assert 'Install' in page.toc_html assert '
<span>plain text in our dialect</span>
''' html = product_markdown.render(text) assert html == expected.lstrip() ``` For new syntax, add a parser rule and renderer handlers together. See {ref}`custom-rules` for an RST-inspired example that creates a new node type and registers HTML, Markdown, and RST rendering behavior.