File size: 4,641 Bytes
8ffb677
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc826a1
8ffb677
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import logging
import re

from fastapi import APIRouter, Form, HTTPException, UploadFile

logger = logging.getLogger(__name__)

router = APIRouter()

plugin = None


def set_plugin_instance(plugin_instance):
    global plugin
    plugin = plugin_instance


@router.get("/status")
async def get_status():
    if plugin is None:
        return {
            "name": "text",
            "enabled": False,
            "message": "插件未加载",
        }
    return plugin.get_status()


@router.post("/process")
async def process_text(text: str = Form(""), mode: str = Form("standard")):
    if plugin is None or not plugin.enabled:
        raise HTTPException(status_code=400, detail="插件未启用")

    if not text:
        raise HTTPException(status_code=400, detail="文本内容不能为空")

    cleaned_text = clean_text(text, mode)

    return {
        "original_text": text,
        "cleaned_text": cleaned_text,
        "original_char_count": len(text),
        "original_line_count": len(text.split("\n")),
        "cleaned_char_count": len(cleaned_text),
        "cleaned_line_count": len(cleaned_text.split("\n")),
    }


@router.post("/upload")
async def upload_file(file: UploadFile):
    if plugin is None or not plugin.enabled:
        raise HTTPException(status_code=400, detail="插件未启用")

    filename = file.filename.lower()
    if not (filename.endswith(".md") or filename.endswith(".txt")):
        raise HTTPException(status_code=400, detail="只支持 .md 和 .txt 文件")

    content_bytes = await file.read()
    try:
        content = content_bytes.decode("utf-8")
    except UnicodeDecodeError:
        raise HTTPException(status_code=400, detail="文件编码不支持,请使用 UTF-8 编码")

    return {
        "filename": file.filename,
        "content": content,
    }


def clean_text(text: str, mode: str = "standard") -> str:
    if mode == "standard":
        lines = text.split("\n")
        cleaned_lines = []
        prev_line_type = None

        for line in lines:
            stripped = line.strip()
            if stripped:
                # 检查当前行类型
                is_heading = re.match(r"^#+\s", stripped) is not None
                is_numbered = re.match(r"^\d+[\.\)]\s+", stripped) is not None
                is_bulleted = re.match(r"^[\-\*]\s+", stripped) is not None

                current_line_type = (
                    "heading"
                    if is_heading
                    else (
                        "numbered"
                        if is_numbered
                        else ("bulleted" if is_bulleted else "other")
                    )
                )

                # 判断是否需要添加空行
                if prev_line_type is None:
                    # 第一行,不需要空行
                    cleaned_lines.append(line)
                elif prev_line_type == "heading" and current_line_type in [
                    "numbered",
                    "bulleted",
                    "other",
                ]:
                    # 标题后直接跟内容,不需要空行
                    cleaned_lines.append(line)
                elif current_line_type in [
                    "numbered",
                    "bulleted",
                ] and prev_line_type in ["numbered", "bulleted"]:
                    # 列表项之间,不需要空行
                    cleaned_lines.append(line)
                else:
                    # 其他情况,添加空行
                    cleaned_lines.append(line)

                prev_line_type = current_line_type
            else:
                # 空行,跳过
                pass

        result = "\n".join(cleaned_lines)
    elif mode == "compact":
        result = re.sub(r"\r\n+", " ", text)
        result = re.sub(r"\r+", " ", result)
        result = re.sub(r"\n+", " ", result)
        result = re.sub(r"[ \t\u00A0\u200B\u200C\u200D\u2060]+", " ", result)
        result = re.sub(r" +", " ", result)
    else:
        result = text

    result = re.sub(r"[,,]", ",", result)

    result = re.sub(r"(?<=\d)\.", "\x00", result)
    result = re.sub(r"[。.](?![a-zA-Z0-9])", "。", result)
    result = re.sub(r"\x00", ".", result)

    result = re.sub(r"[!!]", "!", result)
    result = re.sub(r"[??]", "?", result)
    result = re.sub(r"[;;]", ";", result)
    result = re.sub(r"[::]", ":", result)
    result = re.sub(r"[((]", "(", result)
    result = re.sub(r"[))]", ")", result)
    result = re.sub(r"[【\[]", "【", result)
    result = re.sub(r"[】\]]", "】", result)

    return result.strip()