| @@ -0,0 +1,74 @@ |
| | 1 | module Docs |
| | 2 | class Zsh |
| | 3 | class EntriesFilter < Docs::EntriesFilter |
| | 4 | def get_name |
| | 5 | extract_header_text(at_css('h1.chapter').content) |
| | 6 | end |
| | 7 | |
| | 8 | def additional_entries |
| | 9 | entries = [] |
| | 10 | used_fns = [] |
| | 11 | |
| | 12 | css('h2.section').each do |node| |
| | 13 | type = get_type |
| | 14 | # Linkable anchor sits above <h2>. |
| | 15 | a = node.xpath('preceding-sibling::a').last |
| | 16 | header_text = extract_header_text(node.content) |
| | 17 | |
| | 18 | case type |
| | 19 | when 'Zsh Modules' |
| | 20 | module_name = header_text.match(/The (zsh\/.* Module)/)&.captures&.first |
| | 21 | header_text = module_name if module_name.present? |
| | 22 | when 'Calendar Function System' |
| | 23 | header_text << ' (Calendar)' |
| | 24 | end |
| | 25 | |
| | 26 | entries << [header_text, a['name'], type] unless header_text.start_with?('Description') |
| | 27 | end |
| | 28 | |
| | 29 | # Functions are documented within <dl> elements. |
| | 30 | # Names are wrapped in <dt>, details within <dd>. |
| | 31 | # <dd> can also contain anchors for the next function. |
| | 32 | doc.css('> dl').each do |node| |
| | 33 | type = get_type |
| | 34 | fn_names = node.css('> dt') |
| | 35 | node.css('dd a[name]').each_with_index do |anchor, i| |
| | 36 | if fn_names[i].present? && anchor['name'].present? |
| | 37 | fn_names[i]['id'] = anchor['name'] |
| | 38 | |
| | 39 | # Groups of functions are sometimes comma-delimited. |
| | 40 | # Strip arguments, flags, etc. from function name. |
| | 41 | # Skip flag-only headers. |
| | 42 | fn_names[i].inner_html.split(', ').each do |fn| |
| | 43 | fn.gsub!(/<(?:tt|var)>(.+?)<\/(?:tt|var)>/, '\1') |
| | 44 | fn = fn.split(' ').first |
| | 45 | fn.gsub!(/(?:[\[\(]).*(?:[\]\)]).*$/, '') |
| | 46 | |
| | 47 | # Add context for operators. |
| | 48 | fn << " (#{type})" if fn.length == 1 |
| | 49 | |
| | 50 | if fn.present? && !fn.match?(/^[\-\[]/) && !used_fns.include?(fn) |
| | 51 | used_fns << fn |
| | 52 | entries << [fn, anchor['name'], type] |
| | 53 | end |
| | 54 | end |
| | 55 | end |
| | 56 | end |
| | 57 | end |
| | 58 | |
| | 59 | entries |
| | 60 | end |
| | 61 | |
| | 62 | def get_type |
| | 63 | extract_header_text(at_css('h1.chapter').content) |
| | 64 | end |
| | 65 | |
| | 66 | private |
| | 67 | |
| | 68 | # Extracts text from a string, dropping indices preceding it. |
| | 69 | def extract_header_text(str) |
| | 70 | str.match(/^[\d\.]* (.*)$/)&.captures&.first |
| | 71 | end |
| | 72 | end |
| | 73 | end |
| | 74 | end |