mcp-stata 1.18.0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,88 @@
1
+ """Convert a SMCL file into Markdown.
2
+
3
+ Adapted from https://github.com/sergiocorreia/parse-smcl (MIT). Simplified into
4
+ a single module geared toward MCP, emitting Markdown by default.
5
+ """
6
+
7
+ import os
8
+ import re
9
+ from mcp_stata.native_ops import smcl_to_markdown as rust_smcl_to_markdown
10
+
11
+
12
+ def expand_includes(lines, adopath):
13
+ """Expand INCLUDE directives if ado path is available."""
14
+ if not adopath:
15
+ return lines
16
+ includes = [(i, line[13:].strip()) for (i, line) in enumerate(lines) if line.startswith("INCLUDE help ")]
17
+ if os.path.exists(adopath):
18
+ for i, cmd in reversed(includes):
19
+ fn = os.path.join(adopath, cmd[0], cmd if cmd.endswith(".ihlp") else cmd + ".ihlp")
20
+ try:
21
+ with open(fn, "r", encoding="utf-8") as f:
22
+ content = f.readlines()
23
+ except FileNotFoundError:
24
+ continue
25
+ if content and content[0].startswith("{* *! version"):
26
+ content.pop(0)
27
+ lines[i:i+1] = content
28
+ return lines
29
+
30
+
31
+ def _inline_to_markdown(text: str) -> str:
32
+ """Convert common inline SMCL directives to Markdown."""
33
+
34
+ def repl(match: re.Match) -> str:
35
+ tag = match.group(1).lower()
36
+ content = match.group(2) or ""
37
+ if tag in ("bf", "strong"):
38
+ return f"**{content}**"
39
+ if tag in ("it", "em"):
40
+ return f"*{content}*"
41
+ if tag in ("cmd", "cmdab", "code", "inp", "input", "res", "err", "txt"):
42
+ return f"`{content}`"
43
+ return content
44
+
45
+ text = re.sub(r"\{([a-zA-Z0-9_]+):([^}]*)\}", repl, text)
46
+ text = re.sub(r"\{[^}]*\}", "", text)
47
+ return text
48
+
49
+
50
+ def smcl_to_markdown(smcl_text: str, adopath: str = None, current_file: str = "help") -> str:
51
+ """Convert SMCL text to lightweight Markdown suitable for LLM consumption."""
52
+ if not smcl_text:
53
+ return ""
54
+
55
+ # Try Rust optimization first if no complicated includes are needed
56
+ if not adopath or "INCLUDE help" not in smcl_text:
57
+ res = rust_smcl_to_markdown(smcl_text)
58
+ if res:
59
+ # Add header to match existing Python behavior
60
+ return f"# Help for {current_file}\n" + res
61
+
62
+ lines = smcl_text.splitlines()
63
+ if lines and lines[0].strip() == "{smcl}":
64
+ lines = lines[1:]
65
+
66
+ lines = expand_includes(lines, adopath)
67
+
68
+ title = None
69
+ body_parts = []
70
+
71
+ for raw in lines:
72
+ line = raw.strip()
73
+ if not line:
74
+ continue
75
+ if line.startswith("{title:"):
76
+ title = line[len("{title:") :].rstrip("}")
77
+ continue
78
+ # Paragraph markers
79
+ line = line.replace("{p_end}", "")
80
+ line = re.sub(r"\{p[^}]*\}", "", line)
81
+ body_parts.append(_inline_to_markdown(line))
82
+
83
+ md_parts = [f"# Help for {current_file}"]
84
+ if title:
85
+ md_parts.append(f"\n## {title}\n")
86
+ md_parts.append("\n".join(part for part in body_parts if part).strip())
87
+
88
+ return "\n\n".join(part for part in md_parts if part).strip() + "\n"