Module: MarkdownServer::Plugins::Citations

Defined in:
lib/markdown_server/plugins/bible_citations/citations.rb

Constant Summary collapse

DEFAULT_VERSION =
"CEB"
BIBLE_BOOK_MAP =

Maps every recognised abbreviation to its BibleGateway canonical book name. Keys are sorted longest-first when building the regex so longer forms win.

{
  # -- Old Testament --
  "Genesis"=>"Genesis","Gen."=>"Genesis","Gen"=>"Genesis","Gn"=>"Genesis",
  "Exodus"=>"Exodus","Ex."=>"Exodus","Exo"=>"Exodus","Ex"=>"Exodus",
  "Leviticus"=>"Leviticus","Lev."=>"Leviticus","Lev"=>"Leviticus",
  "Numbers"=>"Numbers","Num."=>"Numbers","Num"=>"Numbers","Nu."=>"Numbers","Nu"=>"Numbers",
  "Deuteronomy"=>"Deuteronomy","Deut."=>"Deuteronomy","Deut"=>"Deuteronomy",
  "Dt."=>"Deuteronomy","Dt"=>"Deuteronomy",
  "Joshua"=>"Joshua","Josh."=>"Joshua","Josh"=>"Joshua",
  "Judges"=>"Judges","Judg."=>"Judges","Judg"=>"Judges",
  "Ruth"=>"Ruth",
  "1 Samuel"=>"1 Samuel","1Samuel"=>"1 Samuel","1 Sam."=>"1 Samuel","1 Sam"=>"1 Samuel","1Sam."=>"1 Samuel",
  "2 Samuel"=>"2 Samuel","2Samuel"=>"2 Samuel","2 Sam."=>"2 Samuel","2 Sam"=>"2 Samuel","2Sam."=>"2 Samuel","2Sa."=>"2 Samuel",
  "1 Kings"=>"1 Kings","1Kings"=>"1 Kings","1 Ki."=>"1 Kings","1Ki."=>"1 Kings","1 Ki"=>"1 Kings","1Ki"=>"1 Kings",
  "2 Kings"=>"2 Kings","2Kings"=>"2 Kings","2 Ki."=>"2 Kings","2Ki."=>"2 Kings","2 Ki"=>"2 Kings","2Ki"=>"2 Kings",
  "1 Chronicles"=>"1 Chronicles","1 Chr."=>"1 Chronicles","1Chr."=>"1 Chronicles","1Ch"=>"1 Chronicles",
  "2 Chronicles"=>"2 Chronicles","2 Chron."=>"2 Chronicles","2Chron."=>"2 Chronicles","2 Chr."=>"2 Chronicles","2Chr."=>"2 Chronicles","2 Ch"=>"2 Chronicles",
  "Ezra"=>"Ezra","Nehemiah"=>"Nehemiah","Neh."=>"Nehemiah","Neh"=>"Nehemiah",
  "Esther"=>"Esther","Esth."=>"Esther","Esth"=>"Esther",
  "Job"=>"Job",
  "Psalms"=>"Psalms","Psalm"=>"Psalms","Psa."=>"Psalms","Psa"=>"Psalms","Ps."=>"Psalms","Ps"=>"Psalms",
  "Proverbs"=>"Proverbs","Prov."=>"Proverbs","Prov"=>"Proverbs","Pr"=>"Proverbs",
  "Ecclesiastes"=>"Ecclesiastes","Eccl."=>"Ecclesiastes","Eccl"=>"Ecclesiastes","Ecc."=>"Ecclesiastes",
  "Song of Songs"=>"Song of Songs","Song"=>"Song of Songs",
  "Isaiah"=>"Isaiah","Isa."=>"Isaiah","Isa"=>"Isaiah","Is"=>"Isaiah",
  "Jeremiah"=>"Jeremiah","Jer."=>"Jeremiah","Jer"=>"Jeremiah","Je"=>"Jeremiah",
  "Lamentations"=>"Lamentations","Lam."=>"Lamentations","Lam"=>"Lamentations","La"=>"Lamentations",
  "Ezekiel"=>"Ezekiel","Ezek."=>"Ezekiel","Ezek"=>"Ezekiel",
  "Daniel"=>"Daniel","Dan."=>"Daniel","Dan"=>"Daniel",
  "Hosea"=>"Hosea","Hos."=>"Hosea","Hos"=>"Hosea",
  "Joel"=>"Joel","Amos"=>"Amos",
  "Obadiah"=>"Obadiah","Jonah"=>"Jonah","Jon."=>"Jonah","Jon"=>"Jonah",
  "Micah"=>"Micah","Mic."=>"Micah","Mic"=>"Micah",
  "Nahum"=>"Nahum","Nah."=>"Nahum","Nah"=>"Nahum",
  "Habakkuk"=>"Habakkuk","Hab."=>"Habakkuk","Hab"=>"Habakkuk",
  "Haggai"=>"Haggai",
  "Zechariah"=>"Zechariah","Zech."=>"Zechariah","Zech"=>"Zechariah","Zec"=>"Zechariah","Zc"=>"Zechariah",
  "Zephaniah"=>"Zephaniah","Zeph."=>"Zephaniah","Zeph"=>"Zephaniah","Zep."=>"Zephaniah","Zep"=>"Zephaniah",
  "Malachi"=>"Malachi","Mal."=>"Malachi","Mal"=>"Malachi",
  # -- New Testament --
  "Matthew"=>"Matthew","Matt."=>"Matthew","Matt"=>"Matthew","Mt."=>"Matthew","Mt"=>"Matthew",
  "Mark"=>"Mark","Mk."=>"Mark","Mk"=>"Mark",
  "Luke"=>"Luke","Lk."=>"Luke","Lk"=>"Luke",
  "John"=>"John","Jn."=>"John","Jn"=>"John","Jo"=>"John",
  "Acts"=>"Acts","Ac."=>"Acts",
  "Romans"=>"Romans","Rom."=>"Romans","Rom"=>"Romans","Ro"=>"Romans",
  "1 Corinthians"=>"1 Corinthians","1Corinthians"=>"1 Corinthians","1 Cor."=>"1 Corinthians","1Cor."=>"1 Corinthians","1 Cor"=>"1 Corinthians","1Cor"=>"1 Corinthians","1Co."=>"1 Corinthians","1Co"=>"1 Corinthians",
  "2 Corinthians"=>"2 Corinthians","2Corinthians"=>"2 Corinthians","2 Cor."=>"2 Corinthians","2Cor."=>"2 Corinthians","2 Cor"=>"2 Corinthians","2Co."=>"2 Corinthians","2Co"=>"2 Corinthians",
  "Galatians"=>"Galatians","Gal."=>"Galatians","Gal"=>"Galatians",
  "Ephesians"=>"Ephesians","Eph."=>"Ephesians","Eph"=>"Ephesians",
  "Philippians"=>"Philippians","Phil."=>"Philippians","Phil"=>"Philippians",
  "Colossians"=>"Colossians","Col."=>"Colossians","Col"=>"Colossians",
  "1 Thessalonians"=>"1 Thessalonians","1 Thess."=>"1 Thessalonians","1Thess."=>"1 Thessalonians","1 Th"=>"1 Thessalonians","1Th"=>"1 Thessalonians",
  "2 Thessalonians"=>"2 Thessalonians","2Thessalonians"=>"2 Thessalonians","2 Thess."=>"2 Thessalonians","2Thess."=>"2 Thessalonians","2 Th"=>"2 Thessalonians","2Th"=>"2 Thessalonians",
  "1 Timothy"=>"1 Timothy","1Timothy"=>"1 Timothy","1 Tim."=>"1 Timothy","1Tim."=>"1 Timothy","1 Tim"=>"1 Timothy","1Tim"=>"1 Timothy","1 Ti."=>"1 Timothy","1Ti."=>"1 Timothy",
  "2 Timothy"=>"2 Timothy","2Timothy"=>"2 Timothy","2 Tim."=>"2 Timothy","2Tim."=>"2 Timothy","2 Tim"=>"2 Timothy","2Tim"=>"2 Timothy","2 Ti."=>"2 Timothy","2Ti."=>"2 Timothy",
  "Titus"=>"Titus","Tit."=>"Titus","Tit"=>"Titus","Ti."=>"Titus",
  "Philemon"=>"Philemon","Philem."=>"Philemon",
  "Hebrews"=>"Hebrews","Hebrew"=>"Hebrews","Heb."=>"Hebrews","Heb"=>"Hebrews","Hb"=>"Hebrews",
  "James"=>"James","Jas."=>"James","Jas"=>"James",
  "1 Peter"=>"1 Peter","1Peter"=>"1 Peter","1 Pet."=>"1 Peter","1Pet."=>"1 Peter","1 Pt."=>"1 Peter","1Pt."=>"1 Peter",
  "2 Peter"=>"2 Peter","2Peter"=>"2 Peter","2 Pet."=>"2 Peter","2Pet."=>"2 Peter","2 Pt."=>"2 Peter","2Pt."=>"2 Peter","2Pe"=>"2 Peter",
  "1 John"=>"1 John","1John"=>"1 John","1 Jn."=>"1 John","1Jn."=>"1 John","1 Jn"=>"1 John","1Jn"=>"1 John",
  "2 John"=>"2 John","2 Jn."=>"2 John","2Jn."=>"2 John",
  "3 John"=>"3 John","3 Jn."=>"3 John","3Jn."=>"3 John",
  "Jude"=>"Jude",
  "Revelation"=>"Revelation","Rev."=>"Revelation","Rev"=>"Revelation",
  # -- Deuterocanonical (present in CEB) --
  "Wisdom of Solomon"=>"Wisdom of Solomon","Wisdom"=>"Wisdom of Solomon","Wis."=>"Wisdom of Solomon",
  "1 Maccabees"=>"1 Maccabees","1Macc."=>"1 Maccabees",
}.freeze
BIBLE_BOOK_MAP_SORTED =

Sorted longest-first for runtime lookup (same order as the regex alternation).

BIBLE_BOOK_MAP.sort_by { |k, _| -k.length }.freeze
BIBLE_CITATION_RE =
Regexp.new(
  "(`[^`]*?`)" \
  "|(`{3}[\\s\\S]*?`{3})" \
  "|(?<!\\!)(\\[[^\\[\\]]*\\]\\([^)]+\\))" \
  "|(#{_citation})",
  Regexp::MULTILINE
)
HTML_BIBLE_CITATION_RE =
Regexp.new(
  "(<script\\b[^>]*>[\\s\\S]*?</script>)" \
  "|(<style\\b[^>]*>[\\s\\S]*?</style>)" \
  "|(<title\\b[^>]*>[\\s\\S]*?</title>)" \
  "|(<select\\b[^>]*>[\\s\\S]*?</select>)" \
  "|(<a\\b[^>]*>[\\s\\S]*?</a>)" \
  "|(<[^>]+>)" \
  "|(#{_citation})",
  Regexp::MULTILINE | Regexp::IGNORECASE
)

Class Method Summary collapse

Class Method Details

.biblegateway_url(canonical, verse, version: DEFAULT_VERSION) ⇒ Object



88
89
90
# File 'lib/markdown_server/plugins/bible_citations/citations.rb', line 88

def self.biblegateway_url(canonical, verse, version: DEFAULT_VERSION)
  "https://www.biblegateway.com/passage/?search=#{CGI.escape("#{canonical} #{verse}")}&version=#{version}"
end


108
109
110
111
112
113
114
115
116
117
118
# File 'lib/markdown_server/plugins/bible_citations/citations.rb', line 108

def self.link_citations(text)
  text.gsub(BIBLE_CITATION_RE) do |m|
    next m if $1 || $2 || $3
    citation = $4
    entry = BIBLE_BOOK_MAP_SORTED.find { |k, _| citation.start_with?(k) }
    next m unless entry
    abbrev, canonical = entry
    verse = citation[abbrev.length..].sub(/\A\.?[ \t]?/, "")
    yield canonical, verse, citation
  end
end


144
145
146
147
148
149
150
151
152
153
154
# File 'lib/markdown_server/plugins/bible_citations/citations.rb', line 144

def self.link_citations_html(html)
  html.gsub(HTML_BIBLE_CITATION_RE) do |m|
    next m if $1 || $2 || $3 || $4 || $5 || $6
    citation = $7
    entry = BIBLE_BOOK_MAP_SORTED.find { |k, _| citation.start_with?(k) }
    next m unless entry
    abbrev, canonical = entry
    verse = citation[abbrev.length..].sub(/\A\.?[ \t]?/, "")
    yield canonical, verse, citation
  end
end

.scrip_url(canonical, verse, version: DEFAULT_VERSION) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/markdown_server/plugins/bible_citations/citations.rb', line 92

def self.scrip_url(canonical, verse, version: DEFAULT_VERSION)
  # Parse chapter and optional starting verse from the verse string
  # verse is e.g. "1:1", "1:1-5", "1", "1-2", "1:1,3,5"
  if verse =~ /\A(\d+)(?::(\d+))?/
    chapter = format("%03d", $1.to_i)
    start_verse = $2
  else
    return biblegateway_url(canonical, verse, version: version)
  end

  encode = ->(s) { URI.encode_www_form_component(s).gsub("+", "%20") }
  url = "https://scrip.risensavior.com/browse/#{encode[version]}/#{encode[canonical]}/#{chapter}.html"
  url += "#v#{start_verse}" if start_verse
  url
end