164 lines
5.7 KiB
Python
164 lines
5.7 KiB
Python
|
|
# HLDP解析器 · 识别光湖语言结构标记
|
|||
|
|
# HLDP://tools/notion-corpus-loader/hldp-parser
|
|||
|
|
|
|||
|
|
import re
|
|||
|
|
from dataclasses import dataclass, field
|
|||
|
|
from typing import List, Optional
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class HLDPBlock:
|
|||
|
|
"""一个HLDP结构块"""
|
|||
|
|
path: str = ""
|
|||
|
|
block_type: str = ""
|
|||
|
|
content: str = ""
|
|||
|
|
cognitive_jump: Optional[str] = None
|
|||
|
|
causal_chain: Optional[str] = None
|
|||
|
|
persona: Optional[str] = None
|
|||
|
|
quality_tag: Optional[str] = None
|
|||
|
|
metadata: dict = field(default_factory=dict)
|
|||
|
|
|
|||
|
|
class HLDPParser:
|
|||
|
|
"""解析HLDP格式的Markdown/HTML内容"""
|
|||
|
|
|
|||
|
|
HLDP_PATH_PATTERN = re.compile(r'HLDP://([\w/-]+)')
|
|||
|
|
|
|||
|
|
COGNITIVE_JUMP_PATTERNS = [
|
|||
|
|
re.compile(r'【认知[跃迁升]*[级点]*】'),
|
|||
|
|
re.compile(r'⚠️\s*([^·\n]{3,30})'),
|
|||
|
|
re.compile(r'核心[认知跃迁]*[::]\s*(.+)'),
|
|||
|
|
re.compile(r'_why[::]\s*(.+)'),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
CAUSAL_PATTERNS = [
|
|||
|
|
re.compile(r'(起点|推导链|终点)[::]\s*(.+)'),
|
|||
|
|
re.compile(r'(.+?)\s*→\s*(.+?)\s*→\s*(.+)'),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
PERSONA_PATTERNS = [
|
|||
|
|
re.compile(r'主权者[::]\s*冰朔.*TCS-0002'),
|
|||
|
|
re.compile(r'人格体[::]\s*(铸渊|霜砚|晨星|舒舒|曜冥|知秋)'),
|
|||
|
|
re.compile(r'(冰朔|霜砚|铸渊|晨星|舒舒)\s*(口述|整理|创建|记录|签发)'),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
QUALITY_PATTERNS = [
|
|||
|
|
re.compile(r'CORPUS-ID[::]\s*(\S+)'),
|
|||
|
|
re.compile(r'语料类型[::]\s*(.+)'),
|
|||
|
|
re.compile(r'(极高|高|中|低)\s*(?:权重|质量)'),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
def parse_markdown(self, text: str) -> List[HLDPBlock]:
|
|||
|
|
"""解析Markdown文本为HLDP结构块"""
|
|||
|
|
blocks = []
|
|||
|
|
lines = text.split('\n')
|
|||
|
|
i = 0
|
|||
|
|
while i < len(lines):
|
|||
|
|
line = lines[i].strip()
|
|||
|
|
if not line:
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
block = HLDPBlock()
|
|||
|
|
heading_match = re.match(r'^(#{1,4})\s+(.+)', line)
|
|||
|
|
if heading_match:
|
|||
|
|
block.block_type = f'heading_{len(heading_match.group(1))}'
|
|||
|
|
block.content = heading_match.group(2)
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
if line.startswith('```'):
|
|||
|
|
code_lines = []
|
|||
|
|
i += 1
|
|||
|
|
while i < len(lines) and not lines[i].strip().startswith('```'):
|
|||
|
|
code_lines.append(lines[i])
|
|||
|
|
i += 1
|
|||
|
|
block.block_type = 'code_block'
|
|||
|
|
block.content = '\n'.join(code_lines)
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
if line.startswith('> '):
|
|||
|
|
block.block_type = 'quote'
|
|||
|
|
block.content = line[2:]
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
for emoji in ['📢', '💡', '⚠️']:
|
|||
|
|
if line.startswith(emoji):
|
|||
|
|
block.block_type = 'callout'
|
|||
|
|
block.content = line
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
if '[子页面]' in line:
|
|||
|
|
block.block_type = 'child_page'
|
|||
|
|
block.content = line
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
if re.match(r'^[-*]\s', line):
|
|||
|
|
block.block_type = 'list_item'
|
|||
|
|
block.content = line
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
if line == '---':
|
|||
|
|
block.block_type = 'divider'
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
continue
|
|||
|
|
block.block_type = 'paragraph'
|
|||
|
|
block.content = line
|
|||
|
|
blocks.append(block)
|
|||
|
|
i += 1
|
|||
|
|
for block in blocks:
|
|||
|
|
self._extract_hldp_annotations(block)
|
|||
|
|
return blocks
|
|||
|
|
|
|||
|
|
def _extract_hldp_annotations(self, block: HLDPBlock):
|
|||
|
|
text = block.content
|
|||
|
|
path_match = self.HLDP_PATH_PATTERN.search(text)
|
|||
|
|
if path_match:
|
|||
|
|
block.path = path_match.group(0)
|
|||
|
|
for pattern in self.COGNITIVE_JUMP_PATTERNS:
|
|||
|
|
match = pattern.search(text)
|
|||
|
|
if match:
|
|||
|
|
block.cognitive_jump = match.group(1) if match.lastindex else match.group(0)
|
|||
|
|
break
|
|||
|
|
for pattern in self.CAUSAL_PATTERNS:
|
|||
|
|
match = pattern.search(text)
|
|||
|
|
if match:
|
|||
|
|
block.causal_chain = match.group(0)
|
|||
|
|
break
|
|||
|
|
for pattern in self.PERSONA_PATTERNS:
|
|||
|
|
match = pattern.search(text)
|
|||
|
|
if match:
|
|||
|
|
block.persona = match.group(0)
|
|||
|
|
break
|
|||
|
|
for pattern in self.QUALITY_PATTERNS:
|
|||
|
|
match = pattern.search(text)
|
|||
|
|
if match:
|
|||
|
|
block.quality_tag = match.group(0)
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
def parse_html(self, html: str) -> List[HLDPBlock]:
|
|||
|
|
text = html
|
|||
|
|
text = re.sub(r'<[^>]+>', '', text)
|
|||
|
|
text = re.sub(r' ', ' ', text)
|
|||
|
|
text = re.sub(r'<', '<', text)
|
|||
|
|
text = re.sub(r'>', '>', text)
|
|||
|
|
text = re.sub(r'&', '&', text)
|
|||
|
|
return self.parse_markdown(text)
|
|||
|
|
|
|||
|
|
def build_cognitive_chain(self, blocks: List[HLDPBlock]) -> List[dict]:
|
|||
|
|
jumps = []
|
|||
|
|
for block in blocks:
|
|||
|
|
if block.cognitive_jump:
|
|||
|
|
jumps.append({'jump_point': block.cognitive_jump, 'context': block.content[:200], 'hldp_path': block.path, 'persona': block.persona})
|
|||
|
|
return jumps
|
|||
|
|
|
|||
|
|
def build_causal_chains(self, blocks: List[HLDPBlock]) -> List[str]:
|
|||
|
|
chains = []
|
|||
|
|
for block in blocks:
|
|||
|
|
if block.causal_chain:
|
|||
|
|
chains.append(block.causal_chain)
|
|||
|
|
return chains
|