Browse Source

Add entries for function calls and operators

spamguy 5 months ago
parent
commit
54d3b88bb1
2 changed files with 39 additions and 6 deletions
  1. 38 5
      lib/docs/filters/zsh/entries.rb
  2. 1 1
      lib/docs/scrapers/zsh.rb

+ 38 - 5
lib/docs/filters/zsh/entries.rb

@@ -7,20 +7,53 @@ module Docs
 
       def additional_entries
         entries = []
-
+        used_fns = []
+        
         css('h2.section').each do |node|
           type = get_type
-
           # Linkable anchor sits above <h2>.
           a = node.xpath('preceding-sibling::a').last
           header_text = extract_header_text(node.content)
 
-          if type == 'Zsh Modules'
-            module_name = header_text.match(/The (zsh\/.*) Module/)&.captures&.first
+          case type
+          when 'Zsh Modules'
+            module_name = header_text.match(/The (zsh\/.* Module)/)&.captures&.first
             header_text = module_name if module_name.present?
+          when 'Calendar Function System'
+            header_text << ' (Calendar)'
           end
 
-          entries << [header_text, a['name'], type] if header_text != 'Description'
+          entries << [header_text, a['name'], type] unless header_text.start_with?('Description')
+        end
+
+        # Functions are documented within <dl> elements.
+        # Names are wrapped in <dt>, details within <dd>.
+        # <dd> can also contain anchors for the next function.
+        doc.css('> dl').each do |node|
+          type = get_type
+          fn_names = node.css('> dt')
+          node.css('dd a[name]').each_with_index do |anchor, i|
+            if fn_names[i].present? && anchor['name'].present?
+              fn_names[i]['id'] = anchor['name']
+
+              # Groups of functions are sometimes comma-delimited.
+              # Strip arguments, flags, etc. from function name.
+              # Skip flag-only headers.
+              fn_names[i].inner_html.split(', ').each do |fn|
+                fn.gsub!(/<(?:tt|var)>(.+?)<\/(?:tt|var)>/, '\1')
+                fn = fn.split(' ').first
+                fn.gsub!(/(?:[\[\(]).*(?:[\]\)]).*$/, '')
+
+                # Add context for operators.
+                fn << " (#{type})" if fn.length == 1
+
+                if fn.present? && !fn.match?(/^[\-\[]/) && !used_fns.include?(fn)
+                  used_fns << fn
+                  entries << [fn, anchor['name'], type]
+                end
+              end
+            end
+          end
         end
 
         entries

+ 1 - 1
lib/docs/scrapers/zsh.rb

@@ -27,7 +27,7 @@ module Docs
 
     def get_latest_version(opts)
       body = fetch('https://zsh.sourceforge.io/Doc/Release', opts)
-      body.scan(/, Zsh version ([0-9.]+)/)[0][0][0...-1]
+      body.scan(/Zsh version ([0-9.]+)/)[0][0]
     end
   end
 end