opml2html 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/opml2html/outline.rb +78 -0
- data/lib/opml2html/renderer.rb +27 -2
- data/lib/opml2html/traverser.rb +32 -36
- data/lib/opml2html/version.rb +1 -1
- data/lib/opml2html.rb +1 -0
- metadata +3 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 8e0131ae0abb115a15cafbf60050e6ee4fff9acd3a84d00d35b0d742f4bccdb2
         | 
| 4 | 
            +
              data.tar.gz: 6d6581e206aa9a10a6b7136bf92256db3a554ec21f5c29123250d383b2337edf
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 6c51c90e04f57ae7e3b7c0193e51a38dd3c4cc697b211c4bc891c238085484c3eeb7b5aa60a77f787c5351edcd29a1dc08b62c4423282393601b78b8da8275c4
         | 
| 7 | 
            +
              data.tar.gz: a9ab4adccc8fcfafb04b4c562fe65fa11d62defc0a51e96a1f0ca22a54b448cab06d110d960eaeffdf0db7b6a331acb6cbf846eb8994471a2f582099322defbe
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,16 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            ## Unreleased
         | 
| 4 4 |  | 
| 5 | 
            +
            ## 0.0.3 - 2025-02-07
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Render description for each outlines.
         | 
| 8 | 
            +
            * Fix outline without XML URI attribute.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            ## 0.0.2 - 2025-02-05
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            * Render XML URI hyperlinks.
         | 
| 13 | 
            +
            * Add more head elements for metadata; owner email and docs.
         | 
| 14 | 
            +
             | 
| 5 15 | 
             
            ## 0.0.1 - 2025-01-05
         | 
| 6 16 |  | 
| 7 17 | 
             
            * Initial release
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            module OPML2HTML
         | 
| 2 | 
            +
              class Outline
         | 
| 3 | 
            +
                def initialize(node)
         | 
| 4 | 
            +
                  node => Element[name: "outline"]
         | 
| 5 | 
            +
                  @node = node
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def deconstruct_keys(*keys)
         | 
| 9 | 
            +
                  result = {}
         | 
| 10 | 
            +
                  keys => [keys]
         | 
| 11 | 
            +
                  keys.each do |key|
         | 
| 12 | 
            +
                    case key
         | 
| 13 | 
            +
                    in :text
         | 
| 14 | 
            +
                      result[:text] = (text or next)
         | 
| 15 | 
            +
                    in :created
         | 
| 16 | 
            +
                      result[:created] = (created or next)
         | 
| 17 | 
            +
                    in :children
         | 
| 18 | 
            +
                      result[:children] = (children or next)
         | 
| 19 | 
            +
                    in :xml_url
         | 
| 20 | 
            +
                      result[:xml_url] = (xml_url or next)
         | 
| 21 | 
            +
                    in :description
         | 
| 22 | 
            +
                      result[:description] = description
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  result
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                private
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def text
         | 
| 31 | 
            +
                  @text and return @text
         | 
| 32 | 
            +
                  attributes => [*, Attr[name: "text", value:], *]
         | 
| 33 | 
            +
                  @text = value
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def created
         | 
| 37 | 
            +
                  @created || @empty_created and return @created
         | 
| 38 | 
            +
                  if attributes in [*, Attr[name: "created", value:], *]
         | 
| 39 | 
            +
                    @created = value
         | 
| 40 | 
            +
                  else
         | 
| 41 | 
            +
                    @empty_created = true
         | 
| 42 | 
            +
                    return
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def xml_url
         | 
| 47 | 
            +
                  @xml_url || @empty_xml_url and return @xml_url
         | 
| 48 | 
            +
                  if attributes in [*, Attr[name: "xmlUrl", value:], *]
         | 
| 49 | 
            +
                    @xml_url = value
         | 
| 50 | 
            +
                  else
         | 
| 51 | 
            +
                    @empty_xml_url = true
         | 
| 52 | 
            +
                    return
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def description
         | 
| 57 | 
            +
                  @description || @empty_description and return @description
         | 
| 58 | 
            +
                  if attributes in [*, Attr[name: "description", value:], *]
         | 
| 59 | 
            +
                    @description = value
         | 
| 60 | 
            +
                  else
         | 
| 61 | 
            +
                    @empty_description = true
         | 
| 62 | 
            +
                    return
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                def attributes
         | 
| 67 | 
            +
                  @attributes and return @attributes
         | 
| 68 | 
            +
                  @node => Element[attributes:]
         | 
| 69 | 
            +
                  @attributes = attributes
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def children
         | 
| 73 | 
            +
                  @children and return @children
         | 
| 74 | 
            +
                  @node => Element[children:]
         | 
| 75 | 
            +
                  @children = children
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
    
        data/lib/opml2html/renderer.rb
    CHANGED
    
    | @@ -31,15 +31,26 @@ module OPML2HTML | |
| 31 31 | 
             
                  @document.metadata.add_child("modified: #{time}<br/>")
         | 
| 32 32 | 
             
                end
         | 
| 33 33 |  | 
| 34 | 
            +
                def head_owner_email(content)
         | 
| 35 | 
            +
                  @document.metadata.add_child("owner email: #{content}")
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                def head_docs(*); end
         | 
| 39 | 
            +
             | 
| 34 40 | 
             
                def head_end
         | 
| 35 41 | 
             
                  @document.head.add_child("<link rel=\"stylesheet\" href=\"#{ @css }\"/>")
         | 
| 36 42 | 
             
                  @document.main.add_child(@document.metadata)
         | 
| 37 43 | 
             
                end
         | 
| 38 44 |  | 
| 39 | 
            -
                def body_outline_heading(value)
         | 
| 40 | 
            -
                  heading = @document.create_element(" | 
| 45 | 
            +
                def body_outline_heading(value, description:, level:)
         | 
| 46 | 
            +
                  heading = @document.create_element("h#{level + 1}")
         | 
| 41 47 | 
             
                  heading.add_child(value)
         | 
| 42 48 | 
             
                  @document.main.add_child(heading)
         | 
| 49 | 
            +
                  if description
         | 
| 50 | 
            +
                    desc = @document.create_element("p")
         | 
| 51 | 
            +
                    desc.content = description
         | 
| 52 | 
            +
                    @document.main.add_child(desc)
         | 
| 53 | 
            +
                  end
         | 
| 43 54 | 
             
                end
         | 
| 44 55 |  | 
| 45 56 | 
             
                def body_outline_text(value)
         | 
| @@ -48,6 +59,20 @@ module OPML2HTML | |
| 48 59 | 
             
                  @document.main.add_child(par)
         | 
| 49 60 | 
             
                end
         | 
| 50 61 |  | 
| 62 | 
            +
                def body_outline_rss(fragment, xml_url, description: nil)
         | 
| 63 | 
            +
                  anchor = @document.create_element("a")
         | 
| 64 | 
            +
                  anchor.add_child(fragment)
         | 
| 65 | 
            +
                  anchor["href"] = xml_url
         | 
| 66 | 
            +
                  par = @document.create_element("p")
         | 
| 67 | 
            +
                  par.add_child(anchor)
         | 
| 68 | 
            +
                  if description
         | 
| 69 | 
            +
                    desc = @document.create_element("p")
         | 
| 70 | 
            +
                    desc.content = description
         | 
| 71 | 
            +
                    par.add_child(desc)
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
                  @document.main.add_child(par)
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
             | 
| 51 76 | 
             
                def body_outline_created(time)
         | 
| 52 77 | 
             
                  # @document.body.add_child("<p style='text-align: right'><small>#{time}</small></p>")
         | 
| 53 78 | 
             
                end
         | 
    
        data/lib/opml2html/traverser.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            require "nokogiri"
         | 
| 2 2 | 
             
            require "time"
         | 
| 3 | 
            +
            require_relative "outline"
         | 
| 3 4 |  | 
| 4 5 | 
             
            module OPML2HTML
         | 
| 5 6 | 
             
              class Traverser
         | 
| @@ -20,27 +21,31 @@ module OPML2HTML | |
| 20 21 | 
             
                private
         | 
| 21 22 |  | 
| 22 23 | 
             
                def parse_document(node)
         | 
| 23 | 
            -
                  node =>  | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 24 | 
            +
                  node => Document[root: Element[name: "opml",
         | 
| 25 | 
            +
                                                 attributes: [Attr[name: "version",
         | 
| 26 | 
            +
                                                                   value: "2.0"]],
         | 
| 27 | 
            +
                                                 children:]]
         | 
| 27 28 | 
             
                  children.each { |child| parse_under_document(child) }
         | 
| 28 29 | 
             
                end
         | 
| 29 30 |  | 
| 30 31 | 
             
                def parse_under_document(node)
         | 
| 32 | 
            +
                  (node in Text) and return
         | 
| 31 33 | 
             
                  case node
         | 
| 32 | 
            -
                  in Text # nop
         | 
| 33 34 | 
             
                  in Element[name: "head", children:]
         | 
| 34 35 | 
             
                    children.each { |child| parse_under_head(child) }
         | 
| 35 36 | 
             
                    @hook.head_end
         | 
| 36 37 | 
             
                  in Element[name: "body", children:]
         | 
| 37 | 
            -
                    children.each  | 
| 38 | 
            +
                    children.each do |child|
         | 
| 39 | 
            +
                      (child in Text) and next
         | 
| 40 | 
            +
                      parse_outline(child, level: 1)
         | 
| 41 | 
            +
                    end
         | 
| 38 42 | 
             
                  else
         | 
| 39 43 | 
             
                    raise Error, node.inspect
         | 
| 40 44 | 
             
                  end
         | 
| 41 45 | 
             
                end
         | 
| 42 46 |  | 
| 43 47 | 
             
                def parse_under_head(node)
         | 
| 48 | 
            +
                  (node in Text) and return
         | 
| 44 49 | 
             
                  case node
         | 
| 45 50 | 
             
                  in Element[name: "title", children: [Text[content:]]]
         | 
| 46 51 | 
             
                    @hook.head_title(content)
         | 
| @@ -55,43 +60,34 @@ module OPML2HTML | |
| 55 60 | 
             
                  in Element[name: "dateModified", children: [Text[content:]]]
         | 
| 56 61 | 
             
                    time = Time.parse(content)
         | 
| 57 62 | 
             
                    @hook.head_date_modified(time)
         | 
| 58 | 
            -
                  in Text | 
| 59 | 
            -
                     | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
             | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                def parse_body_outline_attribute(node)
         | 
| 69 | 
            -
                  case node
         | 
| 70 | 
            -
                  in Attr[name: "text", value:]
         | 
| 71 | 
            -
                    value = DocumentFragment.parse(value)
         | 
| 72 | 
            -
                    @hook.body_outline_text(value)
         | 
| 73 | 
            -
                  in Attr[name: "created", value:]
         | 
| 74 | 
            -
                    time = Time.parse(value)
         | 
| 75 | 
            -
                    @hook.body_outline_created(time)
         | 
| 76 | 
            -
                  in Attr[name: "flNumberedSubs"] # nop
         | 
| 63 | 
            +
                  in Element[name: "ownerEmail", children: [Text[content:]]]
         | 
| 64 | 
            +
                    @hook.head_owner_email(content)
         | 
| 65 | 
            +
                  in Element[name: "docs", children: [Text[content:]]]
         | 
| 66 | 
            +
                    @hook.head_docs(content)
         | 
| 67 | 
            +
                  in Element[name: "ownerId" |
         | 
| 68 | 
            +
                                   "urlUpdateSocket" |
         | 
| 69 | 
            +
                                   "expansionState" |
         | 
| 70 | 
            +
                                   "lastCursor"] # nop
         | 
| 77 71 | 
             
                  else
         | 
| 78 72 | 
             
                    raise Error, node.inspect
         | 
| 79 73 | 
             
                  end
         | 
| 80 74 | 
             
                end
         | 
| 81 75 |  | 
| 82 76 | 
             
                def parse_outline(node, level:)
         | 
| 83 | 
            -
                  case  | 
| 84 | 
            -
                  in  | 
| 85 | 
            -
             | 
| 86 | 
            -
                    value  | 
| 77 | 
            +
                  case Outline.new(node)
         | 
| 78 | 
            +
                  in text:, xml_url:, description:, children: []
         | 
| 79 | 
            +
                    value = DocumentFragment.parse(text)
         | 
| 80 | 
            +
                    @hook.body_outline_rss(value, xml_url, description:)
         | 
| 81 | 
            +
                  in text:, children: []
         | 
| 82 | 
            +
                    value = DocumentFragment.parse(text)
         | 
| 87 83 | 
             
                    @hook.body_outline_text(value)
         | 
| 88 | 
            -
                  in  | 
| 89 | 
            -
                    value = DocumentFragment.parse( | 
| 90 | 
            -
                    @hook.body_outline_heading(value)
         | 
| 91 | 
            -
                    children.each  | 
| 92 | 
            -
             | 
| 93 | 
            -
             | 
| 94 | 
            -
                     | 
| 84 | 
            +
                  in text:, children:, description:
         | 
| 85 | 
            +
                    value = DocumentFragment.parse(text)
         | 
| 86 | 
            +
                    @hook.body_outline_heading(value, description:, level:)
         | 
| 87 | 
            +
                    children.each do |child|
         | 
| 88 | 
            +
                      (child in Text) and next
         | 
| 89 | 
            +
                      parse_outline(child, level: level + 1)
         | 
| 90 | 
            +
                    end
         | 
| 95 91 | 
             
                  end
         | 
| 96 92 | 
             
                end
         | 
| 97 93 | 
             
              end
         | 
    
        data/lib/opml2html/version.rb
    CHANGED
    
    
    
        data/lib/opml2html.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: opml2html
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - gemmaro
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2025-01- | 
| 11 | 
            +
            date: 2025-01-07 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: nokogiri
         | 
| @@ -85,6 +85,7 @@ files: | |
| 85 85 | 
             
            - lib/opml2html.rb
         | 
| 86 86 | 
             
            - lib/opml2html/dumper.rb
         | 
| 87 87 | 
             
            - lib/opml2html/html_document.rb
         | 
| 88 | 
            +
            - lib/opml2html/outline.rb
         | 
| 88 89 | 
             
            - lib/opml2html/renderer.rb
         | 
| 89 90 | 
             
            - lib/opml2html/traverser.rb
         | 
| 90 91 | 
             
            - lib/opml2html/version.rb
         |