diff --git a/README.md b/README.md index cfae338..fd2d495 100755 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ SigProfilerPlotting provides a standard tool for displaying all types of mutatio **INTRODUCTION** -The purpose of this document is to provide a guide for using the SigProfilerPlotting framework and associated functions/tools to visualize the output from SigProfilerExtraction and SigProfilerSimulator. The primary documentation is now maintained in this repository under `docs/`, and the legacy OSF wiki source is at https://osf.io/2aj6t/wiki/home. +The purpose of this document is to provide a guide for using the SigProfilerPlotting framework and associated functions/tools to visualize the output from SigProfilerExtraction and SigProfilerSimulator. The primary documentation is available at https://sigprofilersuite.github.io/SigProfilerPlotting/. -For users that prefer working in an R environment, a wrapper package is provided and can be found and installed from: https://github.com/AlexandrovLab/SigProfilerPlottingR +For users that prefer working in an R environment, a wrapper package is provided and can be found and installed from: https://github.com/SigProfilerSuite/SigProfilerPlottingR ![schematic](schematic.png) diff --git a/docs/assets/osf/2he54.png b/docs/assets/osf/2he54.png new file mode 100644 index 0000000..c8a05da Binary files /dev/null and b/docs/assets/osf/2he54.png differ diff --git a/docs/assets/osf/78htw.png b/docs/assets/osf/78htw.png new file mode 100644 index 0000000..87dfc4a Binary files /dev/null and b/docs/assets/osf/78htw.png differ diff --git a/docs/assets/osf/b7m2t.png b/docs/assets/osf/b7m2t.png new file mode 100644 index 0000000..0582608 Binary files /dev/null and b/docs/assets/osf/b7m2t.png differ diff --git a/docs/assets/osf/cmv6d.png b/docs/assets/osf/cmv6d.png new file mode 100644 index 0000000..4340a41 Binary files /dev/null and b/docs/assets/osf/cmv6d.png differ diff --git a/docs/assets/osf/egk7c.png b/docs/assets/osf/egk7c.png new file mode 100644 index 0000000..faa7d98 Binary files /dev/null and b/docs/assets/osf/egk7c.png differ diff --git a/docs/assets/osf/fgc8z.png b/docs/assets/osf/fgc8z.png new file mode 100644 index 0000000..2d15df0 Binary files /dev/null and b/docs/assets/osf/fgc8z.png differ diff --git a/docs/assets/osf/hfqr2.png b/docs/assets/osf/hfqr2.png new file mode 100644 index 0000000..f5508f1 Binary files /dev/null and b/docs/assets/osf/hfqr2.png differ diff --git a/docs/assets/osf/jcemf.png b/docs/assets/osf/jcemf.png new file mode 100644 index 0000000..924b9f6 Binary files /dev/null and b/docs/assets/osf/jcemf.png differ diff --git a/docs/assets/osf/kmd2f.png b/docs/assets/osf/kmd2f.png new file mode 100644 index 0000000..17cac64 Binary files /dev/null and b/docs/assets/osf/kmd2f.png differ diff --git a/docs/assets/osf/kw8py.png b/docs/assets/osf/kw8py.png new file mode 100644 index 0000000..738efeb Binary files /dev/null and b/docs/assets/osf/kw8py.png differ diff --git a/docs/assets/osf/kwd3y.png b/docs/assets/osf/kwd3y.png new file mode 100644 index 0000000..652c2d4 Binary files /dev/null and b/docs/assets/osf/kwd3y.png differ diff --git a/docs/assets/osf/manifest.json b/docs/assets/osf/manifest.json index 4a1b680..8751fb8 100644 --- a/docs/assets/osf/manifest.json +++ b/docs/assets/osf/manifest.json @@ -1,15 +1,30 @@ { "https://files.osf.io/v1/resources/2aj6t/providers/osfstorage/5c5de3d676653c0018270138?mode=render": "assets/osf/5c5de3d676653c0018270138.png", "https://files.osf.io/v1/resources/2aj6t/providers/osfstorage/5c73d34f8d5d98001a393840?mode=render": "assets/osf/5c73d34f8d5d98001a393840.png", + "https://osf.io/2he54/": "assets/osf/2he54.png", "https://osf.io/2wh7g/": "assets/osf/2wh7g.zip", "https://osf.io/2ydqt/": "assets/osf/2ydqt.bin", "https://osf.io/3rm96/": "assets/osf/3rm96.bin", "https://osf.io/43e76/": "assets/osf/43e76.bin", + "https://osf.io/78htw/": "assets/osf/78htw.png", "https://osf.io/8ubjp/": "assets/osf/8ubjp.bin", + "https://osf.io/b7m2t/": "assets/osf/b7m2t.png", + "https://osf.io/cmv6d/": "assets/osf/cmv6d.png", "https://osf.io/d3e6f/": "assets/osf/d3e6f.bin", + "https://osf.io/egk7c/": "assets/osf/egk7c.png", + "https://osf.io/fgc8z/": "assets/osf/fgc8z.png", "https://osf.io/gmcyp/": "assets/osf/gmcyp.bin", + "https://osf.io/hfqr2/": "assets/osf/hfqr2.png", + "https://osf.io/jcemf/": "assets/osf/jcemf.png", + "https://osf.io/kmd2f/": "assets/osf/kmd2f.png", + "https://osf.io/kw8py/": "assets/osf/kw8py.png", + "https://osf.io/kwd3y/": "assets/osf/kwd3y.png", "https://osf.io/p2fxv/": "assets/osf/p2fxv.bin", "https://osf.io/p3yzs/": "assets/osf/p3yzs.bin", + "https://osf.io/s7wuj/": "assets/osf/s7wuj.png", + "https://osf.io/sc9qj/": "assets/osf/sc9qj.png", "https://osf.io/synw4/": "assets/osf/synw4.bin", + "https://osf.io/uabr5/": "assets/osf/uabr5.png", + "https://osf.io/uxyfv/": "assets/osf/uxyfv.png", "https://osf.io/xd9ym/": "assets/osf/xd9ym.bin" } diff --git a/docs/assets/osf/s7wuj.png b/docs/assets/osf/s7wuj.png new file mode 100644 index 0000000..e89da55 Binary files /dev/null and b/docs/assets/osf/s7wuj.png differ diff --git a/docs/assets/osf/sc9qj.png b/docs/assets/osf/sc9qj.png new file mode 100644 index 0000000..e7850c9 Binary files /dev/null and b/docs/assets/osf/sc9qj.png differ diff --git a/docs/assets/osf/uabr5.png b/docs/assets/osf/uabr5.png new file mode 100644 index 0000000..5730c73 Binary files /dev/null and b/docs/assets/osf/uabr5.png differ diff --git a/docs/assets/osf/uxyfv.png b/docs/assets/osf/uxyfv.png new file mode 100644 index 0000000..cd02514 Binary files /dev/null and b/docs/assets/osf/uxyfv.png differ diff --git a/mkdocs_hooks.py b/mkdocs_hooks.py index 00820de..36be4f9 100644 --- a/mkdocs_hooks.py +++ b/mkdocs_hooks.py @@ -9,13 +9,18 @@ _OSF_IMAGE_SIZE_SUFFIX_RE = re.compile(r"(!\[[^\]]*\]\([^\s)]+)\s+=\d+(?:%x|x)(\))") _OSF_URL_IN_MD_IMAGE_RE = re.compile(r"(!\[[^\]]*\]\()([^) \t\r\n]+)(\))") _OSF_URL_IN_HTML_IMG_RE = re.compile(r'(]*\bsrc=")([^"]+)(")', re.IGNORECASE) -_OSF_EMBED_RE = re.compile(r"@\[(osf)\]\(([^)]+)\)", re.IGNORECASE) +_OSF_EMBED_RE = re.compile(r"@\[\s*osf\s*\]\(([^)]+)\)", re.IGNORECASE) _OSF_WIKI_URL_RE = re.compile(r"https://osf\.io/([^/]+)/wiki/([^\s)\"]+)", re.IGNORECASE) _OSF_MANIFEST_CACHE = None _OSF_MANIFEST_LOADED = False _OSF_MISSING_CACHE = None _OSF_MISSING_LOADED = False _OSF_PLACEHOLDER = "assets/osf/osf_asset_unavailable.svg" +_IMAGE_EXTS = {".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".bmp"} +_URL_REWRITES = { + "https://github.com/AlexandrovLab/SigProfilerPlotting": "https://github.com/SigProfilerSuite/SigProfilerPlotting", + "https://github.com/AlexandrovLab/SigProfilerPlottingR": "https://github.com/SigProfilerSuite/SigProfilerPlottingR", +} # Map OSF wiki page names (decoded from URL) to local docs filenames. _OSF_WIKI_PAGE_TO_DOC = { @@ -47,27 +52,29 @@ def on_page_markdown(markdown: str, page, config, files): line for line in lines if not _TOC_MARKER_LINE_RE.match(line.strip("\n")) ] cleaned = "".join(filtered_lines) + for old, new in _URL_REWRITES.items(): + cleaned = cleaned.replace(old, new) # OSF Wiki sometimes appends non-standard size hints like " =50%x" inside # Markdown image links, which breaks rendering in MkDocs/Markdown. cleaned = _OSF_IMAGE_SIZE_SUFFIX_RE.sub(r"\1\2", cleaned) - # Convert OSF embed markers (e.g. "@[osf](abcde)") into plain links. - cleaned = _OSF_EMBED_RE.sub(r"[OSF](https://osf.io/\2/)", cleaned) - prefix = _page_relative_prefix(page) + manifest = _load_osf_manifest(config) or {} + missing = _load_osf_missing(config) or set() + + # Replace OSF embed markers with local assets if available. + cleaned = _replace_osf_embeds(cleaned, manifest=manifest, missing=missing, prefix=prefix) # Rewrite OSF wiki links to local pages (prevents navigation to downloaded HTML stubs). cleaned = _rewrite_osf_wiki_links(cleaned, prefix=prefix) - manifest = _load_osf_manifest(config) if manifest: for url, rel_path in manifest.items(): if _is_osf_wiki_url(url): continue cleaned = cleaned.replace(url, prefix + rel_path) - missing = _load_osf_missing(config) if missing: cleaned = _replace_blocked_osf_images(cleaned, missing, prefix=prefix) @@ -165,6 +172,27 @@ def html_repl(m): return out +def _replace_osf_embeds(markdown: str, *, manifest: dict, missing: set, prefix: str) -> str: + def repl(m): + raw_id = m.group(1).strip().strip("/") + if not raw_id: + return f"![OSF asset unavailable]({prefix + _OSF_PLACEHOLDER})" + + short_url = f"https://osf.io/{raw_id}/" + rel_path = manifest.get(short_url) if manifest else None + if rel_path: + target = prefix + rel_path + if Path(rel_path).suffix.lower() in _IMAGE_EXTS: + return f"![{raw_id}]({target})" + return f"[Download asset]({target})" + + if short_url in missing: + return f"![OSF asset unavailable]({prefix + _OSF_PLACEHOLDER})" + return f"![OSF asset unavailable]({prefix + _OSF_PLACEHOLDER})" + + return _OSF_EMBED_RE.sub(repl, markdown) + + def _rewrite_osf_wiki_links(markdown: str, *, prefix: str) -> str: """ Rewrite links like: diff --git a/tools/mirror_osf_wiki.py b/tools/mirror_osf_wiki.py index d220d7f..b01fb07 100644 --- a/tools/mirror_osf_wiki.py +++ b/tools/mirror_osf_wiki.py @@ -13,6 +13,7 @@ _OSF_API = "https://api.osf.io/v2" _OSF_FILES_RE = re.compile(r"https://files\.osf\.io/[^\s)\"']+") _OSF_SHORT_RE = re.compile(r"https://osf\.io/[^\s)\"']+") +_OSF_EMBED_RE = re.compile(r"@\[\s*osf\s*\]\(([^)]+)\)", re.IGNORECASE) _OSF_IMAGE_SIZE_SUFFIX_RE = re.compile( r"(https://files\.osf\.io/[^\s)\"']+)\s+=\d+(?:%x|x)$" ) @@ -280,6 +281,11 @@ def _resolve_osf_file_download_url( def _extract_osf_file_urls(markdown: str) -> list[str]: urls = [] + for embed_id in _OSF_EMBED_RE.findall(markdown): + asset_id = embed_id.strip().strip("/") + if asset_id: + urls.append(f"https://osf.io/{asset_id}/") + for raw in _OSF_FILES_RE.findall(markdown) + _OSF_SHORT_RE.findall(markdown): url = raw.rstrip(").,") url = _OSF_IMAGE_SIZE_SUFFIX_RE.sub(r"\1", url)