|
|
@ -0,0 +1,203 @@ |
|
|
|
#!/usr/bin/ruby |
|
|
|
|
|
|
|
# BB_POSTINDEX.RB makes a neat post collection index for Xenforo2 forum |
|
|
|
# posts. Write the post summary text followed by the post URL in |
|
|
|
# any (raw) text editor, with a single newline separating the summary |
|
|
|
# from the URL, but as many blank lines as you want separating each |
|
|
|
# post summary. Optionally, prefix the summary with specific commands |
|
|
|
# to force different output formatting: |
|
|
|
# - !extra categorizes the comment as an extra to be placed at |
|
|
|
# the end of the post collection for the day, |
|
|
|
# - !daystart specifies that the following posts should be placed |
|
|
|
# inside spoiler tags given by the specified day (see example). |
|
|
|
# - !dayend similarly signals the end of the spoiler tags. |
|
|
|
# |
|
|
|
# Example: So the text files I write to sort posts look like: |
|
|
|
# |
|
|
|
# !daystart Saturday, 15 February 2020 |
|
|
|
# |
|
|
|
# Oh, snap! Things just got real ((@UserName) post) |
|
|
|
# https://blahblahblah/page-12#post-3456789 |
|
|
|
# |
|
|
|
# !extra (@WinnerPoster) made an interesting comment |
|
|
|
# https://blahblahblah/page-13#post-4214133 |
|
|
|
# |
|
|
|
# !dayend |
|
|
|
# |
|
|
|
# Then running this script with formats the posts with hyperlinks |
|
|
|
# to the posts, @'s for the credited users, and puts everything |
|
|
|
# behind spoiler tags separating the days. Within each day, the |
|
|
|
# normal posts are formatted with bullet points and a sans serif |
|
|
|
# font for whimsy, and the extra posts appear in a separate section |
|
|
|
# "Informative takes and extras:" at the end of the spoiler. |
|
|
|
|
|
|
|
# For whimsy, use Arial san serif font for the main post list. |
|
|
|
LIST_FORMAT_FONT = "arial" |
|
|
|
|
|
|
|
# Use text macros to dictate the format of the post collection index. |
|
|
|
# !daystart begins a spoiler tag for a given day |
|
|
|
DAY_START = "!daystart" |
|
|
|
|
|
|
|
# !dayend ends the spoiler tag for a given day |
|
|
|
DAY_END = "!dayend" |
|
|
|
|
|
|
|
# !extra specifies that the post is an informative extra, to appear |
|
|
|
# separately in a list at the end |
|
|
|
EXTRA = "!extra" |
|
|
|
|
|
|
|
|
|
|
|
# A class to represent an INDEXEDPOST with a given summary, user, |
|
|
|
# and post hyperlink. Optionally, the post may be specified as |
|
|
|
# an 'extra', in which case no list-style bullet point and sans |
|
|
|
# serif formatting is applied. |
|
|
|
# |
|
|
|
# Example: |
|
|
|
# # Create a new indexed post and print it in default list format |
|
|
|
# post1 = IndexedPost.new("List post (@User post)", "@User", "www.blah#p-1") |
|
|
|
# puts post1 #=> [FONT=arial][URL='www.blah#p-1']○ List post ([/URL] |
|
|
|
# # @User[URL='www.blah#p-1'] post)[/URL][/FONT] |
|
|
|
# |
|
|
|
# # Create a new indexed post and print it in extra format |
|
|
|
# post2 = IndexedPost.new("@User's extra post", "@User", "www.blah", true) |
|
|
|
# puts post2 #=> @User[URL='www.blah']'s extra post[/URL] |
|
|
|
# # And in list form: |
|
|
|
# puts post2.list_format #=> [FONT=arial][URL='www.blah']○ [/URL] |
|
|
|
# #@User[URL='www.blah']'s extra post[/URL][/FONT] |
|
|
|
# |
|
|
|
class IndexedPost |
|
|
|
|
|
|
|
# Create a new indexed post with the given SUMMARY, USER and |
|
|
|
# POST_HYPERLINK. If EXTRA is true, formats the post as an |
|
|
|
# informative extra without any explicit list formatting. |
|
|
|
def initialize(summary, user, post_hyperlink, extra=false) |
|
|
|
@summary = summary |
|
|
|
@user = user |
|
|
|
@post_hyperlink = post_hyperlink |
|
|
|
@extra = extra |
|
|
|
end |
|
|
|
|
|
|
|
# Return a string representation for this post in extra format, |
|
|
|
# i.e. in the regular font with just the hyperlink and no |
|
|
|
# additional formatting. |
|
|
|
def extra_format() |
|
|
|
text = @summary.split(@user).map do |part| |
|
|
|
if (part.length > 0) |
|
|
|
"[URL='" + @post_hyperlink + "']" + part + "[/URL]" |
|
|
|
end |
|
|
|
end |
|
|
|
text.join(" " + @user + " ") |
|
|
|
end |
|
|
|
|
|
|
|
# Return a string representation for this post in list format, |
|
|
|
# i.e. in sans serif font with an ASCII bullet point prepended. |
|
|
|
# TODO: These methods are very similar. Refactor to get rid of the |
|
|
|
# code duplication at some point later? |
|
|
|
def list_format() |
|
|
|
text = ("○ " + @summary).split(@user).map do |part| |
|
|
|
if (part.length > 0) |
|
|
|
"[URL='" + @post_hyperlink + "']" + part + "[/URL]" |
|
|
|
end |
|
|
|
end |
|
|
|
"[FONT=" + LIST_FORMAT_FONT + "]" + text.join(" " + @user + " ") + "[/FONT]" |
|
|
|
end |
|
|
|
|
|
|
|
# Return the printable string representation for this indexed post. |
|
|
|
def to_s() |
|
|
|
if (@extra) |
|
|
|
self.extra_format |
|
|
|
else |
|
|
|
self.list_format |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
# Assume that the file full of posts is the first command line arg |
|
|
|
if (ARGV.length < 1) |
|
|
|
raise(ArgumentError, "No post file specified in command line args") |
|
|
|
else |
|
|
|
posts_file = File.open(ARGV.join("")) |
|
|
|
end |
|
|
|
|
|
|
|
# Read lines from the post collection file (ignoring blank lines), and |
|
|
|
# generate the index structure. |
|
|
|
list_posts = [] |
|
|
|
extra_posts = [] |
|
|
|
day_active = false |
|
|
|
|
|
|
|
line = posts_file.gets.strip |
|
|
|
|
|
|
|
while (line) |
|
|
|
# Skip any preceding white space or blank lines |
|
|
|
line.strip! |
|
|
|
if (not line.empty?) |
|
|
|
case |
|
|
|
when line.start_with?(DAY_START) |
|
|
|
# Start the spoiler tag and refresh the post lists |
|
|
|
puts "[SPOILER=\"" + line.split(DAY_START)[1].strip! + "\"]" |
|
|
|
list_posts = [] |
|
|
|
extra_posts = [] |
|
|
|
day_active = true |
|
|
|
|
|
|
|
when line.start_with?(DAY_END) |
|
|
|
# Print all of the collected list posts |
|
|
|
list_posts.map { |post| puts post.list_format } |
|
|
|
|
|
|
|
# Print all of the collected extra posts in a separate section |
|
|
|
puts "\nInformative takes and extras:" |
|
|
|
extra_posts.map { |post| puts post.extra_format } |
|
|
|
|
|
|
|
# Finally, end the spoiler tag |
|
|
|
puts "[/SPOILER]" |
|
|
|
day_active = false |
|
|
|
|
|
|
|
else |
|
|
|
# If the line begins with !extra, it's an extra/informative post |
|
|
|
extra = line.start_with?(EXTRA) |
|
|
|
if (extra) |
|
|
|
line = line.split(EXTRA)[1].strip |
|
|
|
end |
|
|
|
|
|
|
|
# Parse the user name (assumed to be between a pair of parentheses |
|
|
|
# for simplicity) |
|
|
|
user_with_parens = line.scan(/\(@.+\)(?=['\s])/)[0].strip |
|
|
|
user = user_with_parens[1..-2] |
|
|
|
|
|
|
|
# And remove the extra parentheses in the formatted summary |
|
|
|
summary = line.gsub(user_with_parens, user) |
|
|
|
|
|
|
|
# Grab the next line too for the hyperlink |
|
|
|
post_hyperlink = posts_file.gets.strip |
|
|
|
|
|
|
|
# Instantiate a new post index and add it to the list. |
|
|
|
indexed_post = IndexedPost.new(summary, user, post_hyperlink, extra) |
|
|
|
if (extra) |
|
|
|
extra_posts << indexed_post |
|
|
|
else |
|
|
|
list_posts << indexed_post |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
# Read in the next line |
|
|
|
line = posts_file.gets |
|
|
|
end |
|
|
|
|
|
|
|
# Done reading! Close the collected posts file. |
|
|
|
posts_file.close() |
|
|
|
|
|
|
|
# Check: at the end here, if we still have collected posts for the day, |
|
|
|
# print them all now and close the spoiler tag. |
|
|
|
if (day_active) |
|
|
|
# TODO: Duplicate code from the case. Refactor? |
|
|
|
# Print all of the collected list posts |
|
|
|
list_posts.map { |post| puts post.list_format } |
|
|
|
|
|
|
|
# Print all of the collected extra posts in a separate section |
|
|
|
puts "\nInformative takes and extras:" |
|
|
|
extra_posts.map { |post| puts post.extra_format } |
|
|
|
|
|
|
|
# Finally, end the spoiler tag |
|
|
|
puts "[/SPOILER]" |
|
|
|
end |