Spaces:
Running
Running
| import re | |
| import gradio as gr | |
| MAX_CHARS = 2_000 | |
| UTM_URL = ( | |
| "https://lynote.ai/ai-humanizer?utm_source=huggingface" | |
| "&utm_medium=space&utm_campaign=hf_launch&utm_content=humanizer_lite" | |
| ) | |
| EN_REPLACEMENTS = { | |
| "in today's rapidly evolving world": "today", | |
| "it is important to note that": "", | |
| "it is worth noting that": "", | |
| "serves as a testament to": "shows", | |
| "delve into": "examine", | |
| "leverage": "use", | |
| "seamless": "smooth", | |
| "robust": "reliable", | |
| "game-changer": "useful change", | |
| "in conclusion": "", | |
| "moreover": "also", | |
| "furthermore": "also", | |
| } | |
| ZH_REPLACEMENTS = { | |
| "值得注意的是,": "", | |
| "值得注意的是": "", | |
| "综上所述,": "", | |
| "综上所述": "", | |
| "在当今快速发展的时代": "现在", | |
| "赋能": "帮助", | |
| "助力": "帮助", | |
| "降本增效": "降低成本、提高效率", | |
| "闭环": "完整流程", | |
| "无缝": "顺畅", | |
| } | |
| PROTECTED_PATTERN = re.compile( | |
| r"(`[^`]+`|https?://\S+|(?:[A-Za-z]:)?(?:[/\\][\w.\-]+)+|" | |
| r"\b\d+(?:\.\d+)?(?:%|[A-Za-z]+)?\b|\"[^\"]*\"|'[^']*')" | |
| ) | |
| def _protect(text: str): | |
| protected = [] | |
| def replace(match): | |
| token = f"⟦PROTECTED_{len(protected)}⟧" | |
| protected.append(match.group(0)) | |
| return token | |
| return PROTECTED_PATTERN.sub(replace, text), protected | |
| def _restore(text: str, protected): | |
| for index, value in enumerate(protected): | |
| text = text.replace(f"⟦PROTECTED_{index}⟧", value) | |
| return text | |
| def _replace_case_insensitive(text: str, old: str, new: str): | |
| return re.sub(re.escape(old), new, text, flags=re.IGNORECASE) | |
| def humanize(text: str, voice: str): | |
| original = (text or "").strip() | |
| if not original: | |
| return "Please enter some text.", "No text was processed." | |
| if len(original) > MAX_CHARS: | |
| return original, f"Input is limited to {MAX_CHARS:,} characters in this demo." | |
| working, protected = _protect(original) | |
| changes = [] | |
| for old, new in EN_REPLACEMENTS.items(): | |
| updated = _replace_case_insensitive(working, old, new) | |
| if updated != working: | |
| changes.append(f"Replaced formulaic phrase: {old}") | |
| working = updated | |
| for old, new in ZH_REPLACEMENTS.items(): | |
| if old in working: | |
| working = working.replace(old, new) | |
| changes.append(f"替换模板化表达:{old}") | |
| working = re.sub(r"[ \t]{2,}", " ", working) | |
| working = re.sub(r"\s+([,.;:!?,。;:!?])", r"\1", working) | |
| working = re.sub(r"([.!?。!?])\s*\1+", r"\1", working) | |
| working = re.sub(r"\n{3,}", "\n\n", working).strip(" ,,") | |
| if voice == "Concise": | |
| working = re.sub(r"\b(very|really|highly|extremely)\s+", "", working, flags=re.I) | |
| working = working.replace("非常", "").replace("极其", "") | |
| elif voice == "Professional": | |
| working = re.sub(r"\b(a lot of)\b", "many", working, flags=re.I) | |
| working = working.replace("挺多", "较多").replace("搞定", "完成") | |
| result = _restore(working, protected) | |
| if not changes and result == original: | |
| note = "No high-confidence template phrases were changed." | |
| else: | |
| note = f"Applied {len(changes)} conservative style edit(s). Protected numbers, URLs, paths, code, and quotes." | |
| return result, note | |
| DESCRIPTION = f""" | |
| This free, local demo removes a small set of high-confidence AI-writing clichés while | |
| protecting numbers, URLs, paths, code, and quoted text. It is based on ideas from | |
| [`humanize-text`](https://github.com/lynote-ai/humanize-text) and | |
| [`humanize-text-skill`](https://github.com/lynote-ai/humanize-text-skill). | |
| It is a writing-quality aid—not a guarantee that text will be classified as human. | |
| [Try Lynote's full multi-stage humanizer]({UTM_URL}). | |
| """ | |
| with gr.Blocks(title="Lynote Humanizer Lite") as demo: | |
| gr.Markdown("# ✍️ Lynote Humanizer Lite") | |
| gr.Markdown(DESCRIPTION) | |
| with gr.Row(): | |
| source = gr.Textbox(label="Draft", lines=14, max_lines=20, placeholder="Paste up to 2,000 characters…") | |
| output = gr.Textbox(label="Edited draft", lines=14, max_lines=20) | |
| voice = gr.Radio(["Natural", "Concise", "Professional"], value="Natural", label="Editing style") | |
| run = gr.Button("Humanize conservatively", variant="primary") | |
| notes = gr.Markdown() | |
| run.click(humanize, inputs=[source, voice], outputs=[output, notes]) | |
| gr.Examples( | |
| examples=[ | |
| ["It is worth noting that this robust tool serves as a testament to our commitment to innovation.", "Natural"], | |
| ["值得注意的是,我们通过这套方案赋能团队,形成降本增效闭环。", "Concise"], | |
| ], | |
| inputs=[source, voice], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |