Module: RedditPostToMarkdown

Defined in:
lib/reddit_post_to_markdown.rb,
lib/reddit_post_to_markdown/errors.rb,
lib/reddit_post_to_markdown/version.rb,
lib/reddit_post_to_markdown/post_renderer.rb,
lib/reddit_post_to_markdown/reddit_client.rb,
lib/reddit_post_to_markdown/url_validator.rb

Overview

Top-level namespace for the reddit_post_to_markdown gem.

Defined Under Namespace

Classes: FetchError, InvalidResponseError, NotAPostError, PostRenderer, RedditClient, UrlValidator

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.convert(url, filters: {}, include_comments: true) ⇒ String

Downloads a public Reddit post and returns it as a Markdown string.

The URL must point directly to a single post. Subreddit listings, user profiles, search pages, and similar URLs will raise NotAPostError. Posts that require authentication (private subreddits, age-gated content) are not accessible.

Examples:

Basic usage

markdown = RedditPostToMarkdown.convert(
  "https://www.reddit.com/r/ruby/comments/abc123/some_title/"
)

Without comments

markdown = RedditPostToMarkdown.convert(url, include_comments: false)

With comment filters

markdown = RedditPostToMarkdown.convert(
  url,
  filters: {
    keywords:    ["spam"],
    authors:     ["AutoModerator"],
    min_upvotes: 5,
    regexes:     [/buy now/i],
    message:     "[ removed ]"
  }
)

Parameters:

  • url (String)

    the URL of a public Reddit post

  • include_comments (Boolean) (defaults to: true)

    when false, omits all comments and renders only the post header, title, body, and a reply count of 0. Defaults to true.

  • filters (Hash) (defaults to: {})

    optional hash to suppress comments matching any criterion. Filters are evaluated in the order listed below; the first match replaces the comment body with :message. All keys are optional.

Options Hash (filters:):

  • :keywords (Array<String>)

    case-insensitive substrings; any comment whose body contains one of these strings is replaced

  • :authors (Array<String>)

    usernames (exact, case-sensitive match) whose comments are replaced regardless of content

  • :min_upvotes (Integer)

    comments with fewer upvotes than this value are replaced

  • :regexes (Array<Regexp>)

    patterns matched against the comment body; a match causes the comment to be replaced

  • :message (String)

    the replacement text used when any filter matches (default: “REMOVED DUE TO CUSTOM FILTER(S)”)

Returns:

  • (String)

    the post and its comments rendered as Markdown

Raises:



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/reddit_post_to_markdown.rb', line 57

def self.convert(url, filters: {}, include_comments: true)
  clean = UrlValidator.clean_url(url)

  unless UrlValidator.valid_post_url?(clean)
    raise NotAPostError, "Not a Reddit post URL: #{url}"
  end

  data = RedditClient.new.fetch_post(clean)

   = data.dig(0, "data", "children")
  raise InvalidResponseError, "No post data found in response" if .nil? || .empty?

  post_data    = [0].fetch("data", {})
  replies_data = include_comments ? (data.dig(1, "data", "children") || []) : []

  PostRenderer.render(post_data, replies_data, filters: filters)
end