Danny
Static landing page: Lynote Humanizer Lite
fecd9f0 verified
Raw
History Blame Contribute Delete
4.79 kB
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()