Module: TextTube::LinkReffing

Extended by:
Filterable
Defined in:
lib/texttube/filters/link_reffing.rb

Overview

A class to take links in the format ‘[[link|description]]` and give them a number reference, then output them in markdown format. Note: this is not the same as reference links in markdown, this is more akin to the way books will refer to references or footnotes with a number. P.S. I don’t like to make functions private, we’re all adults, so to use this call Link_reffing#run, #format_links is for internal use.

Author:

  • Iain Barnett

Constant Summary collapse

UNITS =

These are the html codes for superscript 0 - 9

['⁰', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹']
Pattern =

Matches [[link|description]]

/              
  \[\[                      # opening square brackets
    (?<link>\S+)
      \s*\|\s*              # separator
    (?<description>[^\[]+)
  \]\]                      # closing square brackets
/x
Reffer =

a lambda function to transform a link and a number into a markdown reference link.

->(lnk, num){ %Q![#{lnk}](##{num} "Jump to reference")!}
RefHTMLer =

A lambda to transform a link and a number to a HTML reference link.

->(lnk, num){ %Q!<a href="##{num}" title="Jump to reference">#{lnk}</a>!  }
HTMLer =

A lambda to transform a href and a description into an HTML link.

->(lnk, desc){ %Q! <a href="#{lnk}">#{desc}</a>!  }
Markdowner =

A lambda to transform a link and a description into an inline Markdown link.

->(lnk, desc){ %Q! [#{desc}](#{lnk})! }
LeftSq =

HTML code for [

"&#91;"
RightSq =

HTML code for ]

"&#93;"

Class Method Summary collapse

Methods included from Filterable

filter_with, filters

Class Method Details

.divit(id) ⇒ Object

Wraps things in a div. If no id given, no div.

Parameters:

  • id (#to_s)

    The ID attribute for the div.



133
134
135
# File 'lib/texttube/filters/link_reffing.rb', line 133

def self.divit( id )
  "<div markdown='1' id='#{id}'>#{ yield }</div>"
end

This func outputs the link as valid markdown.

Parameters:

  • links (Array<String,String,Integer>)

    A list of 2-length arrays containing the url and the description and the reference number.



121
122
123
124
125
126
127
128
# File 'lib/texttube/filters/link_reffing.rb', line 121

def self.format_links( links )
  links.map{ |(link, description, cur)|
    display_link = link.length >= 45 ? 
                      link[0,45] + "..." : 
                      link
    %Q!\n<a name="#{cur}"></a>#{LeftSq}#{cur}#{RightSq} [#{display_link}](#{link} "#{link}") #{description}\n\n!
  }.join
end

.run(content, options = {}) ⇒ String

Takes markdown content with ref links and turns it into 100% markdown.

Parameters:

  • content (String)

    The markdown content with links to ref.

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

    a customizable set of options

Options Hash (options):

  • :format (#to_s)

    The format of the link you want added. The options are :html, :markdown. The default is :markdown

  • :kind (#to_s)

    The kind of link you want added. The options are :reference, :inline, :none. The default is :reference

  • :div_id (String, nil)

    ID of the div to wrap reference links in. Defaults to “reflinks”. Set to nil or false for no div.

Returns:



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/texttube/filters/link_reffing.rb', line 51

def self.run(content, options={})
  return content if content.blank?
  text = content.dup
  options ||= {}
  kind = options.fetch :kind, :reference
  format = options.fetch( :format, :markdown )
  formatter = if kind == :inline
                if format == :html
                  HTMLer
                else
                  Markdowner
                end
              elsif kind == :none
                nil # none is needed
              else # kind == :reference
                if format == :html
                  RefHTMLer
                else
                  Reffer
                end
              end
  
  div_id =  options.has_key?(:div_id) ? 
              options[:div_id] :
              :reflinks

  cur = 0 #current number

  # if there are no reflinks found
  # this will remain false
  # and `divit` won't be run.
  has_reflinks = false

  links = [] #to store the matches
  
  text.gsub! Pattern do |md|  #block to pass to gsub
    has_reflinks = true
    if kind == :inline
      formatter.($1,$2)
    elsif kind == :none
      ""
    else # kind == :reference
      mags = cur.divmod(10) #get magnitude of number
      ref_tag = mags.first >= 1 ? 
                  UNITS[mags.first] :
                  '' #sort out tens
  
      ref_tag += UNITS[mags.last] #units
      retval = formatter.(ref_tag,cur)
                 
      links << [$1, $2, cur] # add to the words list
      cur += 1 #increase current number
      retval
    end
  end

  if !links.empty?
    if has_reflinks && div_id
      "#{text}\n#{LinkReffing.divit( div_id ) { format_links(links) }}"
    else
      "#{text}\n#{format_links(links)}"
    end
  else
    text
  end
end