Top Level Namespace
Defined Under Namespace
Modules: Mandown
Instance Method Summary collapse
-
#all_chars?(line, char) ⇒ Boolean
Given a string, return true if all the characters are equal to char, or false otherwise.
-
#atx_header?(line) ⇒ Boolean
Return true if the string contains an atx-style header and false otherwise.
-
#get_atx_nesting_level(atx_header) ⇒ Object
Given an atx-style header string of the form ‘# Something …’ or ‘## Something …’, return an integer that indicates the nesting level; ‘#’ would be level 1, ‘##’ would be level 2, etc.
-
#get_heading_level_string(current_nesting, previous_level) ⇒ Object
Given the nesting level of a header (e.g. 2, as returned by get_atx_nesting_level) and a string which specifies the previous heading nesting level (e.g. ‘1.2.1’), return the heading nesting level string for the header (e.g. ‘1.3’, in this example).
-
#get_next_level_string(previous, header) ⇒ Object
Given a string that specifies the previous heading nesting level string (e.g. ‘1.3.1’) and an atx-style header (e.g. ‘## Header’), return the next heading nesting level string (e.g. ‘## 1.4’, in this example) and return it.
-
#get_section_number_from_header(header) ⇒ Object
Take a header string that contains a leading section number and return that number.
-
#insert_header_levels(lines, ignore_bibliography = true) ⇒ Object
Given an array of lines of text, insert appropriate leading section numbers, and return the resulting array.
-
#insert_level_to_atx_header(level_string, header) ⇒ Object
Given a string that specifies the level of a heading (e.g. ‘1.2.3’ such as returned by get_next_level_string, for example), and an atx-style header string, insert the level string into the header and return it.
-
#replace_section_references(lines) ⇒ Object
Take a manuscript, as an array of lines, that has been processed by insert_header_levels, and replace isnstances of ‘sec:some-label’ with the section number that the the label was defined in using ‘label:some-label’.
-
#secdown_documentation ⇒ Object
Define the text that is displayed when the user asks for documentation.
-
#secdown_main ⇒ Object
Read the manuscript from standard input and insert appropriately nested level numbering (e.g. ‘2.1’) and send the result to standard output.
-
#setx_to_atx(lines) ⇒ Object
Given an array of strings, where the (i+1)-th string is the line that appears after the i-th line, convert setx-style headings (those that use underlining to indicate nesting level) to atx style (where a given number of # character are used).
Instance Method Details
#all_chars?(line, char) ⇒ Boolean
Given a string, return true if all the characters are equal to char, or false otherwise. Note that if the line ends with a newline, this will be ignored.
148 149 150 151 152 153 154 |
# File 'lib/secdown_lib.rb', line 148 def all_chars?(line, char) return false if line.nil? line = line.strip chars_array = line.split('').uniq return true if chars_array.length == 1 && chars_array[0] == char return false end |
#atx_header?(line) ⇒ Boolean
Return true if the string contains an atx-style header and false otherwise.
127 128 129 130 131 132 133 |
# File 'lib/secdown_lib.rb', line 127 def atx_header?(line) if /#+ \w*/.match(line).nil? false else true end end |
#get_atx_nesting_level(atx_header) ⇒ Object
Given an atx-style header string of the form ‘# Something …’ or ‘## Something …’, return an integer that indicates the nesting level; ‘#’ would be level 1, ‘##’ would be level 2, etc. Returns 0 if the text is not an atx-style header.
139 140 141 142 143 |
# File 'lib/secdown_lib.rb', line 139 def get_atx_nesting_level(atx_header) # Check that we have an atx header. return 0 if !atx_header?(atx_header) atx_header.split[0].length # Return the number of leading # characters. end |
#get_heading_level_string(current_nesting, previous_level) ⇒ Object
Given the nesting level of a header (e.g. 2, as returned by get_atx_nesting_level) and a string which specifies the previous heading nesting level (e.g. ‘1.2.1’), return the heading nesting level string for the header (e.g. ‘1.3’, in this example).
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/secdown_lib.rb', line 186 def get_heading_level_string(current_nesting, previous_level) if previous_level.split('.').length < current_nesting # The case where we need to move to a deeper nesting level. previous_level + '.1' else # The case where we need to remain at the current, or move up, a level. t = previous_level.split('.') t = t[0..current_nesting-1] t[-1] = (t[-1].to_i + 1).to_s t.join('.') end end |
#get_next_level_string(previous, header) ⇒ Object
Given a string that specifies the previous heading nesting level string (e.g. ‘1.3.1’) and an atx-style header (e.g. ‘## Header’), return the next heading nesting level string (e.g. ‘## 1.4’, in this example) and return it.
202 203 204 205 206 207 208 209 |
# File 'lib/secdown_lib.rb', line 202 def get_next_level_string(previous, header) # Get the level and the string to insert. if previous == '' '1' else get_heading_level_string(get_atx_nesting_level(header), previous) end end |
#get_section_number_from_header(header) ⇒ Object
Take a header string that contains a leading section number and return that number.
244 245 246 247 248 249 250 251 |
# File 'lib/secdown_lib.rb', line 244 def get_section_number_from_header(header) tmp = header.scan(/(\d+((\.\d)+))/) if tmp.empty? header.scan(/(\d+)/)[0][0] else tmp[0][0] end end |
#insert_header_levels(lines, ignore_bibliography = true) ⇒ Object
Given an array of lines of text, insert appropriate leading section numbers, and return the resulting array. By default, ignore the bibliography line.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/secdown_lib.rb', line 223 def insert_header_levels(lines, ignore_bibliography = true) lines = setx_to_atx(lines) # Convert setx-style headers to atx-style. current_level_string = '0' ret_val = [] lines.each do |line| if atx_header?(line) && /# Bibliography/.match(line) && ignore_bibliography ret_val.push(line) elsif atx_header?(line) current_level_string = get_next_level_string(current_level_string, line) ret_val.push( insert_level_to_atx_header(current_level_string, line)) else ret_val.push(line) end end ret_val end |
#insert_level_to_atx_header(level_string, header) ⇒ Object
Given a string that specifies the level of a heading (e.g. ‘1.2.3’ such as returned by get_next_level_string, for example), and an atx-style header string, insert the level string into the header and return it.
215 216 217 218 |
# File 'lib/secdown_lib.rb', line 215 def insert_level_to_atx_header(level_string, header) level = get_atx_nesting_level(header) header[0..level-1] + ' ' + level_string + header[level..-1] end |
#replace_section_references(lines) ⇒ Object
Take a manuscript, as an array of lines, that has been processed by insert_header_levels, and replace isnstances of ‘sec:some-label’ with the section number that the the label was defined in using ‘label:some-label’. Remove lines that contain the label definition and return the result.
258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 |
# File 'lib/secdown_lib.rb', line 258 def replace_section_references(lines) # First parse the lines to get a mapping between the label names and the # section numbers they appear in. current_section_number = nil label_section_map = {} # Will map labels to section numbers. ret_val = [] lines.each do |line| # Get the label:some-label string, if it is on this line, as an array. label_string_arr = line.scan(/^label:\w+[-_\.]*\w*/) if atx_header?(line) current_section_number = get_section_number_from_header(line) elsif !label_string_arr.empty? label = label_string_arr[0].split('label:')[1] # Get the label. label_section_map[label] = current_section_number line = nil # Kill off the label. else # Do nothing. end ret_val.push(line) unless line.nil? end # Now process ret_val to replace instances of 'sec:some-label' with 'section # 3.2' or whatever. ret_val.each_index do |i| label_section_map.each_pair do |key, value| ret_val[i].gsub!("sec:#{key}", "section #{value}") end p ret_val[i] end ret_val end |
#secdown_documentation ⇒ Object
Define the text that is displayed when the user asks for documentation
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 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 117 118 119 120 121 122 123 |
# File 'lib/secdown_lib.rb', line 21 def secdown_documentation <<END secdown --- part of the Mandown set of tools. secdown processes standard input and: * inserts section numbers in titles; * allows references to other sections to be made. Copyright © 2008 Chris Rose. Distributed according to the GNU General Public License. Usage: ------ cat infile.txt | secdown > outfile.txt Syntax: ------- Standard Markdown provides two ways to indicate headings: the first style uses '=' or '-' characters placed under the title (for first and second level headings respectively); the second uses leading '#' characters, where the number of '#' characters indicates the nesting level. ------------------------------- Example ------------------------------------- This is a level 1 heading ========================= This is a level 2 heading ------------------------- # This is also a level 1 heading ## This is also a level 2 heading ## So is this ### This is a level 3 heading ### So is this ------------------------------- End of example ------------------------------ secdown inserts heading numbers into headings. For example, the above example would be given the following heading numbers (the actual result is not shown, but this indicates the resulting numbering): 1 This is a level 1 heading 1.1 This is a level 2 heading 2 This is also a level 1 heading 2.1 This is also a level 2 heading 2.2 So is this 2.2.1 This is a level 3 heading 2.2.2 So is this secdown outputs all headings in the '#'-based style, irrespective of the input style. secdown does not insert a heading number for '# Bibliography'. secdown provides a way to reference other sections. To label a section (or subsection, etc.), insert a line containing a label of the form 'label:some-label' somehwere in the section you want to reference. To reference the section, use the syntax 'sec:some-label'. secdown will remove the label definitions and replace the section references with something like 'section 1.2'. ------------------------------- Example ------------------------------------- The following text # This is a heading label:first-section This is a reference to the second section, sec:second-section. # This is another heading label:second-section This is a reference to the first section, sec:first-section. Would be turned into # 1 This is a heading This is a reference to the second section, section 2. # 2 This is another heading This is a reference to the first section, section 1. ------------------------------- End of example ------------------------------ See also: --------- Markdown -- http://daringfireball.net/projects/markdown/ Pandoc -- http://johnmacfarlane.net/pandoc/ END end |
#secdown_main ⇒ Object
Read the manuscript from standard input and insert appropriately nested level numbering (e.g. ‘2.1’) and send the result to standard output.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/secdown_lib.rb', line 295 def secdown_main # Handle request for documentation. if ARGV.length > 0 && ARGV[0] == '--help' puts secdown_documentation exit end # Read the file from standard input. lines = STDIN.readlines # Insert the level numbers. manuscript = insert_header_levels(lines) # Send the processed manuscript to standard output. STDOUT.puts(manuscript) end |
#setx_to_atx(lines) ⇒ Object
Given an array of strings, where the (i+1)-th string is the line that appears after the i-th line, convert setx-style headings (those that use underlining to indicate nesting level) to atx style (where a given number of # character are used). Return the resulting array of lines.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/secdown_lib.rb', line 160 def setx_to_atx(lines) ret_val = [] lines.each_index do |i| # Get the next two lines, if there are, else quit looking. if lines.length > i-2 this_line = lines[i] next_line = lines[i+1] if all_chars?(next_line, '=') ret_val.push('# ' + this_line) elsif all_chars?(next_line, '-') ret_val.push('## ' + this_line) elsif all_chars?(this_line, '-') || all_chars?(this_line, '=') # Do nothing, but keep this condition in! else ret_val.push(this_line) end end end ret_val end |