|
|
@@ -11,6 +11,9 @@ import (
|
|
|
|
|
|
"miniflux.app/v2/internal/model"
|
|
|
"miniflux.app/v2/internal/urllib"
|
|
|
+
|
|
|
+ "golang.org/x/text/cases"
|
|
|
+ "golang.org/x/text/language"
|
|
|
)
|
|
|
|
|
|
type rule struct {
|
|
|
@@ -18,50 +21,7 @@ type rule struct {
|
|
|
args []string
|
|
|
}
|
|
|
|
|
|
-// Rewriter modify item contents with a set of rewriting rules.
|
|
|
-func Rewriter(entryURL string, entry *model.Entry, customRewriteRules string) {
|
|
|
- rulesList := getPredefinedRewriteRules(entryURL)
|
|
|
- if customRewriteRules != "" {
|
|
|
- rulesList = customRewriteRules
|
|
|
- }
|
|
|
-
|
|
|
- rules := parseRules(rulesList)
|
|
|
- rules = append(rules, rule{name: "add_pdf_download_link"})
|
|
|
-
|
|
|
- slog.Debug("Rewrite rules applied",
|
|
|
- slog.Any("rules", rules),
|
|
|
- slog.String("entry_url", entryURL),
|
|
|
- )
|
|
|
-
|
|
|
- for _, rule := range rules {
|
|
|
- applyRule(entryURL, entry, rule)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func parseRules(rulesText string) (rules []rule) {
|
|
|
- scan := scanner.Scanner{Mode: scanner.ScanIdents | scanner.ScanStrings}
|
|
|
- scan.Init(strings.NewReader(rulesText))
|
|
|
-
|
|
|
- for {
|
|
|
- switch scan.Scan() {
|
|
|
- case scanner.Ident:
|
|
|
- rules = append(rules, rule{name: scan.TokenText()})
|
|
|
-
|
|
|
- case scanner.String:
|
|
|
- if l := len(rules) - 1; l >= 0 {
|
|
|
- text := scan.TokenText()
|
|
|
- text, _ = strconv.Unquote(text)
|
|
|
-
|
|
|
- rules[l].args = append(rules[l].args, text)
|
|
|
- }
|
|
|
-
|
|
|
- case scanner.EOF:
|
|
|
- return
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func applyRule(entryURL string, entry *model.Entry, rule rule) {
|
|
|
+func (rule rule) applyRule(entryURL string, entry *model.Entry) {
|
|
|
switch rule.name {
|
|
|
case "add_image_title":
|
|
|
entry.Content = addImageTitle(entryURL, entry.Content)
|
|
|
@@ -82,7 +42,7 @@ func applyRule(entryURL string, entry *model.Entry, rule rule) {
|
|
|
case "add_pdf_download_link":
|
|
|
entry.Content = addPDFLink(entryURL, entry.Content)
|
|
|
case "nl2br":
|
|
|
- entry.Content = replaceLineFeeds(entry.Content)
|
|
|
+ entry.Content = strings.ReplaceAll(entry.Content, "\n", "<br>")
|
|
|
case "convert_text_link", "convert_text_links":
|
|
|
entry.Content = replaceTextLinks(entry.Content)
|
|
|
case "fix_medium_images":
|
|
|
@@ -122,11 +82,11 @@ func applyRule(entryURL string, entry *model.Entry, rule rule) {
|
|
|
case "add_castopod_episode":
|
|
|
entry.Content = addCastopodEpisode(entryURL, entry.Content)
|
|
|
case "base64_decode":
|
|
|
+ selector := "body"
|
|
|
if len(rule.args) >= 1 {
|
|
|
- entry.Content = applyFuncOnTextContent(entry.Content, rule.args[0], decodeBase64Content)
|
|
|
- } else {
|
|
|
- entry.Content = applyFuncOnTextContent(entry.Content, "body", decodeBase64Content)
|
|
|
+ selector = rule.args[0]
|
|
|
}
|
|
|
+ entry.Content = applyFuncOnTextContent(entry.Content, selector, decodeBase64Content)
|
|
|
case "add_hn_links_using_hack":
|
|
|
entry.Content = addHackerNewsLinksUsing(entry.Content, "hack")
|
|
|
case "add_hn_links_using_opener":
|
|
|
@@ -136,7 +96,46 @@ func applyRule(entryURL string, entry *model.Entry, rule rule) {
|
|
|
case "remove_tables":
|
|
|
entry.Content = removeTables(entry.Content)
|
|
|
case "remove_clickbait":
|
|
|
- entry.Title = removeClickbait(entry.Title)
|
|
|
+ entry.Title = cases.Title(language.English).String(strings.ToLower(entry.Title))
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Rewriter modify item contents with a set of rewriting rules.
|
|
|
+func Rewriter(entryURL string, entry *model.Entry, customRewriteRules string) {
|
|
|
+ rulesList := getPredefinedRewriteRules(entryURL)
|
|
|
+ if customRewriteRules != "" {
|
|
|
+ rulesList = customRewriteRules
|
|
|
+ }
|
|
|
+
|
|
|
+ rules := parseRules(rulesList)
|
|
|
+ rules = append(rules, rule{name: "add_pdf_download_link"})
|
|
|
+
|
|
|
+ slog.Debug("Rewrite rules applied",
|
|
|
+ slog.Any("rules", rules),
|
|
|
+ slog.String("entry_url", entryURL),
|
|
|
+ )
|
|
|
+
|
|
|
+ for _, rule := range rules {
|
|
|
+ rule.applyRule(entryURL, entry)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func parseRules(rulesText string) (rules []rule) {
|
|
|
+ scan := scanner.Scanner{Mode: scanner.ScanIdents | scanner.ScanStrings}
|
|
|
+ scan.Init(strings.NewReader(rulesText))
|
|
|
+
|
|
|
+ for {
|
|
|
+ switch scan.Scan() {
|
|
|
+ case scanner.Ident:
|
|
|
+ rules = append(rules, rule{name: scan.TokenText()})
|
|
|
+ case scanner.String:
|
|
|
+ if l := len(rules) - 1; l >= 0 {
|
|
|
+ text, _ := strconv.Unquote(scan.TokenText())
|
|
|
+ rules[l].args = append(rules[l].args, text)
|
|
|
+ }
|
|
|
+ case scanner.EOF:
|
|
|
+ return
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|