Initial standalone crypto_okx with one-click deploy.
Add deploy/manage.sh bootstrap for git.bz121.com/dekun/crypto_okx and point docs at this repo. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
"""Markdown → HTML for system guide / options docs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
|
||||
def render_markdown_html(md_text: str) -> str:
|
||||
try:
|
||||
import markdown # type: ignore
|
||||
|
||||
return markdown.markdown(
|
||||
md_text,
|
||||
extensions=["tables", "fenced_code", "nl2br", "sane_lists"],
|
||||
)
|
||||
except Exception:
|
||||
return _simple_md_html(md_text)
|
||||
|
||||
|
||||
def _simple_md_html(md_text: str) -> str:
|
||||
from html import escape
|
||||
|
||||
lines = md_text.replace("\r\n", "\n").replace("\r", "\n").splitlines()
|
||||
out: list[str] = []
|
||||
i = 0
|
||||
in_code = False
|
||||
code_buf: list[str] = []
|
||||
list_buf: list[str] = []
|
||||
list_ordered = False
|
||||
|
||||
def flush_list() -> None:
|
||||
nonlocal list_buf, list_ordered
|
||||
if not list_buf:
|
||||
return
|
||||
tag = "ol" if list_ordered else "ul"
|
||||
out.append(f"<{tag}>")
|
||||
for item in list_buf:
|
||||
out.append(f"<li>{_inline_md(item)}</li>")
|
||||
out.append(f"</{tag}>")
|
||||
list_buf = []
|
||||
|
||||
def flush_code() -> None:
|
||||
nonlocal code_buf, in_code
|
||||
if not code_buf:
|
||||
return
|
||||
out.append(f"<pre><code>{escape(chr(10).join(code_buf))}</code></pre>")
|
||||
code_buf = []
|
||||
in_code = False
|
||||
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.strip().startswith("```"):
|
||||
flush_list()
|
||||
if in_code:
|
||||
flush_code()
|
||||
else:
|
||||
in_code = True
|
||||
i += 1
|
||||
continue
|
||||
if in_code:
|
||||
code_buf.append(line)
|
||||
i += 1
|
||||
continue
|
||||
if re.match(r"^\s*\|", line) and i + 1 < len(lines) and re.match(r"^\s*\|?\s*[-:| ]+\|", lines[i + 1]):
|
||||
flush_list()
|
||||
header = [c.strip() for c in line.strip().strip("|").split("|")]
|
||||
i += 2
|
||||
rows: list[list[str]] = []
|
||||
while i < len(lines) and re.match(r"^\s*\|", lines[i]):
|
||||
rows.append([c.strip() for c in lines[i].strip().strip("|").split("|")])
|
||||
i += 1
|
||||
out.append("<table><thead><tr>" + "".join(f"<th>{_inline_md(h)}</th>" for h in header) + "</tr></thead><tbody>")
|
||||
for row in rows:
|
||||
out.append("<tr>" + "".join(f"<td>{_inline_md(c)}</td>" for c in row) + "</tr>")
|
||||
out.append("</tbody></table>")
|
||||
continue
|
||||
if re.match(r"^#{1,3}\s+", line):
|
||||
flush_list()
|
||||
m = re.match(r"^(#{1,3})\s+(.*)$", line)
|
||||
if m:
|
||||
level = len(m.group(1))
|
||||
out.append(f"<h{level}>{_inline_md(m.group(2))}</h{level}>")
|
||||
i += 1
|
||||
continue
|
||||
if line.strip() == "---":
|
||||
flush_list()
|
||||
out.append("<hr>")
|
||||
i += 1
|
||||
continue
|
||||
if line.startswith(">"):
|
||||
flush_list()
|
||||
out.append(f"<blockquote>{_inline_md(line.lstrip('>').strip())}</blockquote>")
|
||||
i += 1
|
||||
continue
|
||||
m = re.match(r"^(\d+)\.\s+(.*)$", line.strip())
|
||||
if m:
|
||||
if list_buf and not list_ordered:
|
||||
flush_list()
|
||||
list_ordered = True
|
||||
list_buf.append(m.group(2))
|
||||
i += 1
|
||||
continue
|
||||
if re.match(r"^[-*]\s+", line.strip()):
|
||||
if list_buf and list_ordered:
|
||||
flush_list()
|
||||
list_ordered = False
|
||||
list_buf.append(re.sub(r"^[-*]\s+", "", line.strip()))
|
||||
i += 1
|
||||
continue
|
||||
if not line.strip():
|
||||
flush_list()
|
||||
i += 1
|
||||
continue
|
||||
flush_list()
|
||||
out.append(f"<p>{_inline_md(line.strip())}</p>")
|
||||
i += 1
|
||||
flush_list()
|
||||
flush_code()
|
||||
return "\n".join(out)
|
||||
|
||||
|
||||
def _inline_md(text: str) -> str:
|
||||
from html import escape
|
||||
|
||||
s = escape(text)
|
||||
s = re.sub(r"`([^`]+)`", r"<code>\1</code>", s)
|
||||
s = re.sub(r"\*\*([^*]+)\*\*", r"<strong>\1</strong>", s)
|
||||
return s
|
||||
Reference in New Issue
Block a user