package threadspost import ( "fmt" "strings" ) // LineCount returns non-empty lines after normalizing newlines. func LineCount(text string) int { text = strings.ReplaceAll(text, "\r\n", "\n") text = strings.ReplaceAll(text, "\r", "\n") n := 0 for _, line := range strings.Split(text, "\n") { if strings.TrimSpace(line) != "" { n++ } } return n } // MimicLengthRange returns a suggested min/max rune count when imitating referenceText. func MimicLengthRange(referenceText string) (min, max int) { ref := RuneLen(referenceText) if ref <= 0 { return ViralSweetMin, ViralSweetMax } min = int(float64(ref) * 0.75) max = int(float64(ref) * 1.25) if min < 20 { min = 20 } if max < min+10 { max = min + 10 } if max > MaxPublishRunes { max = MaxPublishRunes } if min > max { min = max } return min, max } // MimicLengthGuidance builds prompt text for rewrite/mimic flows. func MimicLengthGuidance(referenceText string) string { referenceText = strings.TrimSpace(referenceText) if referenceText == "" { return "" } refRunes := RuneLen(referenceText) refLines := LineCount(referenceText) min, max := MimicLengthRange(referenceText) lineMin, lineMax := refLines, refLines if refLines > 1 { lineMin = refLines - 1 if lineMin < 1 { lineMin = 1 } lineMax = refLines + 1 } return fmt.Sprintf( "【篇幅(仿寫)】參考原文約 %d 字、%d 行。產出正文請控制在 %d~%d 字、約 %d~%d 行,不要明顯比參考長很多或短很多。精簡優先:刪掉重複鋪陳、無關細節、雞湯總結與多餘轉折;每一句都要推進故事或情緒,不然就砍掉。", refRunes, refLines, min, max, lineMin, lineMax, ) }