| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // Copyright 2017 Frédéric Guillot. All rights reserved.
- // Use of this source code is governed by the Apache 2.0
- // license that can be found in the LICENSE file.
- package rewrite // import "miniflux.app/reader/rewrite"
- import (
- "strconv"
- "strings"
- "text/scanner"
- "miniflux.app/logger"
- "miniflux.app/url"
- )
- type rule struct {
- name string
- args []string
- }
- // Rewriter modify item contents with a set of rewriting rules.
- func Rewriter(entryURL, entryContent, customRewriteRules string) string {
- rulesList := getPredefinedRewriteRules(entryURL)
- if customRewriteRules != "" {
- rulesList = customRewriteRules
- }
- rules := parseRules(rulesList)
- rules = append(rules, rule{name: "add_pdf_download_link"})
- logger.Debug(`[Rewrite] Applying rules %v for %q`, rules, entryURL)
- for _, rule := range rules {
- entryContent = applyRule(entryURL, entryContent, rule)
- }
- return entryContent
- }
- 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, entryContent string, rule rule) string {
- switch rule.name {
- case "add_image_title":
- entryContent = addImageTitle(entryURL, entryContent)
- case "add_mailto_subject":
- entryContent = addMailtoSubject(entryURL, entryContent)
- case "add_dynamic_image":
- entryContent = addDynamicImage(entryURL, entryContent)
- case "add_youtube_video":
- entryContent = addYoutubeVideo(entryURL, entryContent)
- case "add_invidious_video":
- entryContent = addInvidiousVideo(entryURL, entryContent)
- case "add_youtube_video_using_invidious_player":
- entryContent = addYoutubeVideoUsingInvidiousPlayer(entryURL, entryContent)
- case "add_youtube_video_from_id":
- entryContent = addYoutubeVideoFromId(entryContent)
- case "add_pdf_download_link":
- entryContent = addPDFLink(entryURL, entryContent)
- case "nl2br":
- entryContent = replaceLineFeeds(entryContent)
- case "convert_text_link", "convert_text_links":
- entryContent = replaceTextLinks(entryContent)
- case "fix_medium_images":
- entryContent = fixMediumImages(entryURL, entryContent)
- case "use_noscript_figure_images":
- entryContent = useNoScriptImages(entryURL, entryContent)
- case "replace":
- // Format: replace("search-term"|"replace-term")
- if len(rule.args) >= 2 {
- entryContent = replaceCustom(entryContent, rule.args[0], rule.args[1])
- } else {
- logger.Debug("[Rewrite] Cannot find search and replace terms for replace rule %s", rule)
- }
- case "remove":
- // Format: remove("#selector > .element, .another")
- if len(rule.args) >= 1 {
- entryContent = removeCustom(entryContent, rule.args[0])
- } else {
- logger.Debug("[Rewrite] Cannot find selector for remove rule %s", rule)
- }
- case "add_castopod_episode":
- entryContent = addCastopodEpisode(entryURL, entryContent)
- case "base64_decode":
- if len(rule.args) >= 1 {
- entryContent = applyFuncOnTextContent(entryContent, rule.args[0], decodeBase64Content)
- } else {
- entryContent = applyFuncOnTextContent(entryContent, "body", decodeBase64Content)
- }
- case "parse_markdown":
- entryContent = parseMarkdown(entryContent)
- }
- return entryContent
- }
- func getPredefinedRewriteRules(entryURL string) string {
- urlDomain := url.Domain(entryURL)
- for domain, rules := range predefinedRules {
- if strings.Contains(urlDomain, domain) {
- return rules
- }
- }
- return ""
- }
|