diff --git a/results.json b/results.json index 1fa5218..e272ec8 100644 --- a/results.json +++ b/results.json @@ -24,10 +24,11 @@ "pageKeywords": "Brain, Diagnosis, Pathology-Based Diagnoses, Stroke, Cerebral Ischemia and Infarction, Hypotensive Cerebral Infarction", "reasons": [ "Breadcrumbs", + "Content", "Keywords", "Title" ], - "snippet": "", + "snippet": "## KEY FACTS - ### Terminology - Hypotensive cerebral infarction (HCI) - Insufficient cerebral blood flow to meet...", "linked_info": { "anatomy": { "exists": true, @@ -66,7 +67,7 @@ "exists": true, "links": [ { - "title": "Cerebral Infarction (Acute, Multiple Embolic)", + "title": "Multiple Embolic Cerebral Infarctions", "docid": "6dfc36d2-a561-49d5-a391-e740ba94e5d7" }, { @@ -84,5 +85,130 @@ ] } } + }, + { + "path": "docs_md/articles/multiple-embolic-cerebral-infarctions_6dfc36d2-a561-49d5-a391-e740ba94e5d7.md", + "title": "Multiple Embolic Cerebral Infarctions", + "docid": "6dfc36d2-a561-49d5-a391-e740ba94e5d7", + "breadcrumbs": [ + "Brain", + "Diagnosis", + "Pathology-Based Diagnoses", + "Stroke", + "Cerebral Ischemia and Infarction", + "Multiple Embolic Cerebral Infarctions" + ], + "authors": [ + { + "key": "cdbaaa96-a7b4-4498-a355-a2823a7d9e26", + "value": "Kelly A. Dahlstrom, DO" + }, + { + "key": "8d5254e9-8dda-478b-8f08-bdee97a32c79", + "value": "Karen L. Salzman, MD, FACR" + } + ], + "pageKeywords": "Brain, Diagnosis, Pathology-Based Diagnoses, Stroke, Cerebral Ischemia and Infarction, Multiple Embolic Cerebral Infarctions", + "reasons": [ + "Content" + ], + "snippet": "...laque features - ### Top Differential Diagnoses - Hypotensive cerebral infarction - Vasculitis - Multiple sclerosis - Parenchyma...", + "linked_info": { + "anatomy": { + "exists": false, + "links": [] + }, + "differential": { + "exists": true, + "links": [ + { + "title": "Hypotensive Cerebral Infarction", + "docid": "a3d3dd38-629e-42fc-9d0d-9a03a39781eb" + }, + { + "title": "Vasculitis", + "docid": "490b3aed-37e2-4ec6-95dd-76efc734490f" + }, + { + "title": "Multiple Sclerosis", + "docid": "abe95a5e-394f-411b-aca6-72ab160a1d0d" + }, + { + "title": "Parenchymal Metastases", + "docid": "2cf0bd40-4597-4c0b-83e4-74340304b98f" + } + ] + } + } + }, + { + "path": "docs_md/articles/confluent-white-matter-lesions_33041afc-b606-4d06-8fb6-495849d9659a.md", + "title": "Confluent White Matter Lesions", + "docid": "33041afc-b606-4d06-8fb6-495849d9659a", + "breadcrumbs": [ + "Brain", + "Differential Diagnosis", + "Supratentorial Brain Parenchyma", + "Anatomically Based Differentials", + "Confluent White Matter Lesions" + ], + "authors": [ + { + "key": "8d5254e9-8dda-478b-8f08-bdee97a32c79", + "value": "Karen L. Salzman, MD, FACR" + } + ], + "pageKeywords": "Brain, Differential Diagnosis, Supratentorial Brain Parenchyma, Anatomically Based Differentials, Confluent White Matter Lesions", + "reasons": [ + "Content" + ], + "snippet": "...ccur alone or in association with Alzheimer disease - **Hypotensive Cerebral Infarction** - Infarct resulting from insufficient cerebral...", + "linked_info": { + "anatomy": { + "exists": false, + "links": [] + }, + "differential": { + "exists": false, + "links": [] + } + } + }, + { + "path": "docs_md/articles/multiple-brain-hyperintensities-t2-flair-common_c4edb275-a180-4910-9cad-da08c1138784.md", + "title": "Multiple Brain Hyperintensities (T2/FLAIR), Common", + "docid": "c4edb275-a180-4910-9cad-da08c1138784", + "breadcrumbs": [ + "Brain", + "Differential Diagnosis", + "Brain Parenchyma, General", + "Modality-Specific Imaging Findings", + "Multiple Brain Hyperintensities (T2/FLAIR), Common" + ], + "authors": [ + { + "key": "1fa14dfd-71ea-4960-908e-e720313bc63a", + "value": "Santhosh Gaddikeri, MD" + }, + { + "key": "30ce27b2-237f-4aff-a88f-65ead356335b", + "value": "Marinos Kontzialis, MD" + } + ], + "pageKeywords": "Brain, Differential Diagnosis, Brain Parenchyma, General, Modality-Specific Imaging Findings, Multiple Brain Hyperintensities (T2/FLAIR), Common", + "reasons": [ + "Content" + ], + "snippet": "...ges (on GRE/SWI) - BG/thalami, brainstem, cerebellum - Confluent WM disease (centrum semiovale, corona radiata) - **Ac...", + "linked_info": { + "anatomy": { + "exists": false, + "links": [] + }, + "differential": { + "exists": false, + "links": [] + } + } } ] \ No newline at end of file diff --git a/tools/search_md_gui.py b/tools/search_md_gui.py index 648afd4..5048b5f 100644 --- a/tools/search_md_gui.py +++ b/tools/search_md_gui.py @@ -21,8 +21,15 @@ import asyncio from nicegui import ui, app import re -app.add_static_files('/images', 'docs_md/articles/images') -app.add_static_files('/document/images', 'docs_md/articles/images') +_current_dir = os.path.dirname(os.path.abspath(__file__)) +_articles_dir = os.path.abspath(os.path.join(_current_dir, '..', 'docs_md', 'articles')) +_images_dir = os.path.join(_articles_dir, 'images') +_img_dir = os.path.join(_articles_dir, 'img') + +app.add_static_files('/images', _images_dir) +app.add_static_files('/document/images', _images_dir) +app.add_static_files('/img', _img_dir) +app.add_static_files('/document/img', _img_dir) import shutil import subprocess @@ -821,6 +828,45 @@ def search_page() -> None: # build UI run_conv_button = ui.button('Run conversion', on_click=lambda: asyncio.create_task(run_dtm_handler()), color='primary') +def linkify_references(content: str, root: str = 'docs_md/articles') -> str: + def replace_anatomy(match): + raw_text = match.group(0) + uuid = match.group(1) + fm, _, _ = search_md.get_doc_by_id(root, uuid) + if fm: + title = fm.get('title') or fm.get('pageTitle') or uuid + return f'[{title}](/document/{uuid})' + return raw_text + + anatomy_pattern = re.compile(r'(?:[a-zA-Z0-9\-]+/)?ANATOMY:([a-f0-9\-]{36})', re.IGNORECASE) + content = anatomy_pattern.sub(replace_anatomy, content) + + def replace_ddx(match): + raw_text = match.group(0) + uuid = match.group(1) + fm, _, _ = search_md.get_doc_by_id(root, uuid) + if fm: + title = fm.get('title') or fm.get('pageTitle') or uuid + return f'[{title}](/document/{uuid})' + return raw_text + + ddx_pattern = re.compile(r'DDX:([a-f0-9\-]{36})', re.IGNORECASE) + content = ddx_pattern.sub(replace_ddx, content) + + def replace_standard_links(match): + label = match.group(1) + uuid = match.group(3) + fm, _, _ = search_md.get_doc_by_id(root, uuid) + if fm: + return f'[{label}](/document/{uuid})' + return match.group(0) + + markdown_link_pattern = re.compile(r'\[([^\]]+)\]\(((?:https?://app\.statdx\.com)?/document/[^/]+/([a-f0-9\-]{36}))\)') + content = markdown_link_pattern.sub(replace_standard_links, content) + + return content + + @ui.page('/document/{identifier}') def render_doc_page(identifier: str): ui.add_head_html(''' @@ -899,6 +945,8 @@ def render_doc_page(identifier: str): ''') fm, content, path = search_md.get_doc_by_id('docs_md/articles', identifier) + if fm and content: + content = linkify_references(content, 'docs_md/articles') if not fm: with ui.column().classes('w-full items-center justify-center p-12 gap-4'): ui.icon('warning', size='4rem', color='negative')