fyodor 0.2.8 → 0.3.1
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/README.md +31 -6
 - data/lib/fyodor/book.rb +2 -2
 - data/lib/fyodor/config_getter.rb +43 -16
 - data/lib/fyodor/output_generator.rb +72 -0
 - data/lib/fyodor/output_writer.rb +6 -4
 - data/lib/fyodor/version.rb +1 -1
 - metadata +6 -6
 - data/lib/fyodor/md_generator.rb +0 -96
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: eeecee4acc8d86b2d4e21dc8071d5c1fa29ef5c7a7873f1c8c9cf0a693f2a9fb
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: ebd27239fbb6da6fb2fc601ed4138212ded181f135c42c99a4aff45046dcc802
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 41bd104a94086a9d42d99b85b99b17105013b38f2fa15f8623af86e64f7b648503748770edbec5d22681700b48f56b577c73c555a2b845f59f0d4b5d0b4590db
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 06575a116669bbd2f1758ef772a5fbb091bfb22381f7cc44315c2f9973a7384174434c8a82443f1dc0ddef934a5f5fc2f49f53cb2caf5f9033897c0449843695
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -8,7 +8,7 @@ This application parses `My Clippings.txt` from your Kindle and generates a mark 
     | 
|
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            [For samples of the output, click here.](docs/output_demo)
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            To read more about the motivation and what problem it tries to solve, [check this blog post](https://rafaelc.org/ 
     | 
| 
      
 11 
     | 
    
         
            +
            To read more about the motivation and what problem it tries to solve, [check this blog post](https://rafaelc.org/posts/export-all-your-kindle-highlights-and-notes/).
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            ## Features
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
         @@ -18,10 +18,18 @@ To read more about the motivation and what problem it tries to solve, [check thi 
     | 
|
| 
       18 
18 
     | 
    
         
             
            - Easily configurable for your language, allowing you to get all features and beautiful output.
         
     | 
| 
       19 
19 
     | 
    
         
             
            - This software goes some length to be locale agnostic: basic parsing should work without configuration for any language. It should also work even if your clippings file has multiple locales.
         
     | 
| 
       20 
20 
     | 
    
         
             
            - Bookmarks are printed together and notes are formatted differently, for better visualization.
         
     | 
| 
       21 
     | 
    
         
            -
            -  
     | 
| 
      
 21 
     | 
    
         
            +
            - By default, output in a format that is clean and easy to edit/fiddle around: markdown.
         
     | 
| 
      
 22 
     | 
    
         
            +
            - Entirely customizable output, through templates, in the format you prefer.
         
     | 
| 
       22 
23 
     | 
    
         | 
| 
       23 
24 
     | 
    
         
             
            This program is based on the clippings file generated by Kindle 2019, but should work with other models.
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
            ## Limitations
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            We are limited by the data Kindle makes available through `My Clippings.txt`. This means:
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            - We don't have chapter information.
         
     | 
| 
      
 31 
     | 
    
         
            +
            - We can’t guess all entries that were deleted.
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       25 
33 
     | 
    
         
             
            ## Installation
         
     | 
| 
       26 
34 
     | 
    
         | 
| 
       27 
35 
     | 
    
         
             
            Install Ruby and run:
         
     | 
| 
         @@ -46,10 +54,10 @@ Fyodor has an optional configuration file, which is used for the following. 
     | 
|
| 
       46 
54 
     | 
    
         | 
| 
       47 
55 
     | 
    
         
             
            If your Kindle is not in English, you should tell Fyodor how some things are called by your `My Clippings.txt` (e.g. highlights, pages, etc). _Fyodor should still work without configuration, but you won't take advantage of many features, resulting in a dirtier output._
         
     | 
| 
       48 
56 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
            1. Download the sample config to `~/.config/fyodor.toml` or `$XDG_CONFIG_HOME/fyodor.toml`:
         
     | 
| 
      
 57 
     | 
    
         
            +
            1. Download the sample config to `~/.config/fyodor/fyodor.toml` or `$XDG_CONFIG_HOME/fyodor/fyodor.toml`:
         
     | 
| 
       50 
58 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
            ```
         
     | 
| 
       52 
     | 
    
         
            -
            $  
     | 
| 
      
 59 
     | 
    
         
            +
            ```sh
         
     | 
| 
      
 60 
     | 
    
         
            +
            $ curl https://raw.githubusercontent.com/rc2dev/fyodor/master/docs/fyodor.toml.sample --create-dirs -o ~/.config/fyodor/fyodor.toml
         
     | 
| 
       53 
61 
     | 
    
         
             
            ```
         
     | 
| 
       54 
62 
     | 
    
         | 
| 
       55 
63 
     | 
    
         
             
            2. Open both the configuration and your `My Clippings.txt` in your preferred editor. Change the values in the `[parser]` section to mirror what you get in `My Clippings.txt`.
         
     | 
| 
         @@ -71,6 +79,23 @@ time = "Adicionado:" 
     | 
|
| 
       71 
79 
     | 
    
         | 
| 
       72 
80 
     | 
    
         
             
            In the configuration file you can also set whether to print the time of each entry. On `[output]`, set `time` to `true` or `false`.
         
     | 
| 
       73 
81 
     | 
    
         | 
| 
      
 82 
     | 
    
         
            +
            ### Templating
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            You may change the structure of the files output by Fyodor by providing your own template.
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            Simply place a ERB template at `~/.config/fyodor/template.erb` or `$XDG_CONFIG_HOME/fyodor/template.erb` and Fyodor will use it automatically.
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            The default template can be found [here](share/template.erb). You can use any method or attribute available [on this class](lib/fyodor/output_generator.rb).
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
            ### Extension
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            If you want to change the extension of the output files - typically after changing the template -, set `extension` on `fyodor.toml`. For example, to change it to HTML:
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            ```toml
         
     | 
| 
      
 95 
     | 
    
         
            +
            [output]
         
     | 
| 
      
 96 
     | 
    
         
            +
            extension = "html"
         
     | 
| 
      
 97 
     | 
    
         
            +
            ```
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
       74 
99 
     | 
    
         
             
            ## Usage
         
     | 
| 
       75 
100 
     | 
    
         | 
| 
       76 
101 
     | 
    
         
             
            ```
         
     | 
| 
         @@ -98,4 +123,4 @@ If you like Fyodor, you can show your support here: 
     | 
|
| 
       98 
123 
     | 
    
         | 
| 
       99 
124 
     | 
    
         
             
            Licensed under [GPLv3](LICENSE)
         
     | 
| 
       100 
125 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
            Copyright (C) 2019- 
     | 
| 
      
 126 
     | 
    
         
            +
            Copyright (C) 2019-2022 [Rafael Cavalcanti](https://rafaelc.org/dev)
         
     | 
    
        data/lib/fyodor/book.rb
    CHANGED
    
    | 
         @@ -26,8 +26,8 @@ module Fyodor 
     | 
|
| 
       26 
26 
     | 
    
         
             
                end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                def basename
         
     | 
| 
       29 
     | 
    
         
            -
                  base = @author.to_s.empty? ? @title : "#{@author} - #{@title}"
         
     | 
| 
       30 
     | 
    
         
            -
                  base.strip 
     | 
| 
      
 29 
     | 
    
         
            +
                  base = @author.to_s.empty? ? "Author N/A - #{@title}" : "#{@author} - #{@title}"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  base.strip
         
     | 
| 
       31 
31 
     | 
    
         
             
                end
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         
             
                def count_types
         
     | 
    
        data/lib/fyodor/config_getter.rb
    CHANGED
    
    | 
         @@ -4,7 +4,11 @@ require "toml" 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            module Fyodor
         
     | 
| 
       6 
6 
     | 
    
         
             
              class ConfigGetter
         
     | 
| 
       7 
     | 
    
         
            -
                 
     | 
| 
      
 7 
     | 
    
         
            +
                CONFIG_NAME = "fyodor.toml"
         
     | 
| 
      
 8 
     | 
    
         
            +
                TEMPLATE_NAME = "template.erb"
         
     | 
| 
      
 9 
     | 
    
         
            +
                DEFAULT_TEMPLATE_PATH = File.dirname(__FILE__) + "/../../share/template.erb"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                DEFAULTS = {
         
     | 
| 
       8 
12 
     | 
    
         
             
                  "parser" => {
         
     | 
| 
       9 
13 
     | 
    
         
             
                    "highlight" => "Your Highlight",
         
     | 
| 
       10 
14 
     | 
    
         
             
                    "note" => "Your Note",
         
     | 
| 
         @@ -15,7 +19,8 @@ module Fyodor 
     | 
|
| 
       15 
19 
     | 
    
         
             
                    "time" => "Added on"
         
     | 
| 
       16 
20 
     | 
    
         
             
                  },
         
     | 
| 
       17 
21 
     | 
    
         
             
                  "output" => {
         
     | 
| 
       18 
     | 
    
         
            -
                    "time" => false
         
     | 
| 
      
 22 
     | 
    
         
            +
                    "time" => false,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    "extension" => "md"
         
     | 
| 
       19 
24 
     | 
    
         
             
                  }
         
     | 
| 
       20 
25 
     | 
    
         
             
                }
         
     | 
| 
       21 
26 
     | 
    
         | 
| 
         @@ -28,30 +33,52 @@ module Fyodor 
     | 
|
| 
       28 
33 
     | 
    
         | 
| 
       29 
34 
     | 
    
         
             
                def get_config
         
     | 
| 
       30 
35 
     | 
    
         
             
                  Hash.include CoreExtensions::Hash::Merging
         
     | 
| 
       31 
     | 
    
         
            -
                  print_path
         
     | 
| 
       32 
36 
     | 
    
         | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
       34 
     | 
    
         
            -
                   
     | 
| 
      
 37 
     | 
    
         
            +
                  @config_path = get_path(CONFIG_NAME)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  print_config_path
         
     | 
| 
      
 39 
     | 
    
         
            +
                  user_config = @config_path.nil? ? {} : TOML.load_file(@config_path)
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  config = DEFAULTS.deep_merge(user_config)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  config["output"]["template"] = template
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  config
         
     | 
| 
       35 
45 
     | 
    
         
             
                end
         
     | 
| 
       36 
46 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                def  
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
      
 47 
     | 
    
         
            +
                def get_path(name)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  possible_dirs.each do |d|
         
     | 
| 
      
 49 
     | 
    
         
            +
                    path = d + name
         
     | 
| 
      
 50 
     | 
    
         
            +
                    return path if path.exist?
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  return nil
         
     | 
| 
       39 
54 
     | 
    
         
             
                end
         
     | 
| 
       40 
55 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                def  
     | 
| 
       42 
     | 
    
         
            -
                  return @ 
     | 
| 
      
 56 
     | 
    
         
            +
                def possible_dirs
         
     | 
| 
      
 57 
     | 
    
         
            +
                  return @possible_dirs unless @possible_dirs.nil?
         
     | 
| 
       43 
58 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                  @ 
     | 
| 
       45 
     | 
    
         
            -
                  @ 
     | 
| 
       46 
     | 
    
         
            -
                  @ 
     | 
| 
      
 59 
     | 
    
         
            +
                  @possible_dirs = []
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @possible_dirs << Pathname.new(ENV["XDG_CONFIG_HOME"]) + "fyodor" unless ENV["XDG_CONFIG_HOME"].nil?
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @possible_dirs << Pathname.new("~/.config/fyodor").expand_path
         
     | 
| 
       47 
62 
     | 
    
         
             
                end
         
     | 
| 
       48 
63 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                def  
     | 
| 
       50 
     | 
    
         
            -
                  if  
     | 
| 
       51 
     | 
    
         
            -
                    puts "No config found: using defaults.\n 
     | 
| 
      
 64 
     | 
    
         
            +
                def print_config_path
         
     | 
| 
      
 65 
     | 
    
         
            +
                  if @config_path.nil?
         
     | 
| 
      
 66 
     | 
    
         
            +
                    puts "No config found: using defaults.\n"
         
     | 
| 
       52 
67 
     | 
    
         
             
                  else
         
     | 
| 
       53 
     | 
    
         
            -
                    puts "Using config at #{ 
     | 
| 
      
 68 
     | 
    
         
            +
                    puts "Using config at #{@config_path}.\n"
         
     | 
| 
       54 
69 
     | 
    
         
             
                  end
         
     | 
| 
       55 
70 
     | 
    
         
             
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                def template
         
     | 
| 
      
 73 
     | 
    
         
            +
                  template_path = get_path(TEMPLATE_NAME) || DEFAULT_TEMPLATE_PATH
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  if template_path == DEFAULT_TEMPLATE_PATH
         
     | 
| 
      
 76 
     | 
    
         
            +
                    puts "No template found: using default.\n\n"
         
     | 
| 
      
 77 
     | 
    
         
            +
                  else
         
     | 
| 
      
 78 
     | 
    
         
            +
                    puts "Using template at #{template_path}.\n\n"
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                  File.read(template_path)
         
     | 
| 
      
 82 
     | 
    
         
            +
                end
         
     | 
| 
       56 
83 
     | 
    
         
             
              end
         
     | 
| 
       57 
84 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "fyodor/strings"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "erb"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module Fyodor
         
     | 
| 
      
 5 
     | 
    
         
            +
              class OutputGenerator
         
     | 
| 
      
 6 
     | 
    
         
            +
                include Strings
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(book, config)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @book = book
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @config = config
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def content
         
     | 
| 
      
 14 
     | 
    
         
            +
                  ERB.new(@config["template"], nil, '-').result(binding)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                private
         
     | 
| 
      
 19 
     | 
    
         
            +
                
         
     | 
| 
      
 20 
     | 
    
         
            +
                def regular_entries
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @book.reject { |entry| entry.type == Entry::TYPE[:bookmark] }
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def bookmarks
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @book.select { |entry| entry.type == Entry::TYPE[:bookmark] }
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def render_entries(entries)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  output = ""
         
     | 
| 
      
 30 
     | 
    
         
            +
                  entries.each do |entry|
         
     | 
| 
      
 31 
     | 
    
         
            +
                    output += "- #{item_text(entry)}\n\n"
         
     | 
| 
      
 32 
     | 
    
         
            +
                    output += "  #{item_desc(entry)}\n\n" unless item_desc(entry).empty?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  end
         
     | 
| 
      
 34 
     | 
    
         
            +
                  output.strip
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def item_text(entry)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  case entry.type
         
     | 
| 
      
 39 
     | 
    
         
            +
                  when Entry::TYPE[:bookmark]
         
     | 
| 
      
 40 
     | 
    
         
            +
                    "#{page(entry)}"
         
     | 
| 
      
 41 
     | 
    
         
            +
                  when Entry::TYPE[:note]
         
     | 
| 
      
 42 
     | 
    
         
            +
                    "_Note:_ #{entry.text.strip}"
         
     | 
| 
      
 43 
     | 
    
         
            +
                  else
         
     | 
| 
      
 44 
     | 
    
         
            +
                    "#{entry.text.strip}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def item_desc(entry)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  return entry.desc unless entry.desc_parsed?
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  case entry.type
         
     | 
| 
      
 52 
     | 
    
         
            +
                  when Entry::TYPE[:bookmark]
         
     | 
| 
      
 53 
     | 
    
         
            +
                    time(entry)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  else
         
     | 
| 
      
 55 
     | 
    
         
            +
                    (type(entry) + " @ " + page(entry) + " " + time(entry)).strip
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                def page(entry)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  ((entry.page.nil? ? "" : "page #{entry.page}, ") +
         
     | 
| 
      
 61 
     | 
    
         
            +
                    (entry.loc.nil? ? "" : "loc. #{entry.loc}")).delete_suffix(", ")
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def time(entry)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @config["time"] ? "[#{entry.time}]" : ""
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def type(entry)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  SINGULAR[entry.type]
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/fyodor/output_writer.rb
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "fyodor/ 
     | 
| 
      
 1 
     | 
    
         
            +
            require "fyodor/output_generator"
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Fyodor
         
     | 
| 
       4 
4 
     | 
    
         
             
              class OutputWriter
         
     | 
| 
         @@ -12,7 +12,7 @@ module Fyodor 
     | 
|
| 
       12 
12 
     | 
    
         
             
                def write_all
         
     | 
| 
       13 
13 
     | 
    
         
             
                  puts "\nWriting to #{@output_dir}..." unless @library.empty?
         
     | 
| 
       14 
14 
     | 
    
         
             
                  @library.each do |book|
         
     | 
| 
       15 
     | 
    
         
            -
                    content =  
     | 
| 
      
 15 
     | 
    
         
            +
                    content = OutputGenerator.new(book, @config).content
         
     | 
| 
       16 
16 
     | 
    
         
             
                    File.open(path(book), "w") { |f| f.puts(content) }
         
     | 
| 
       17 
17 
     | 
    
         
             
                  end
         
     | 
| 
       18 
18 
     | 
    
         
             
                end
         
     | 
| 
         @@ -21,11 +21,13 @@ module Fyodor 
     | 
|
| 
       21 
21 
     | 
    
         
             
                private
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                def path(book)
         
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
      
 24 
     | 
    
         
            +
                  basename = book.basename.gsub(/[?*:|\/"<>]/,"_")
         
     | 
| 
      
 25 
     | 
    
         
            +
                  extension = @config["extension"]
         
     | 
| 
      
 26 
     | 
    
         
            +
                  path = @output_dir + "#{basename}.#{extension}"
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                  i = 2
         
     | 
| 
       27 
29 
     | 
    
         
             
                  while(path.exist?)
         
     | 
| 
       28 
     | 
    
         
            -
                    path = @output_dir + " 
     | 
| 
      
 30 
     | 
    
         
            +
                    path = @output_dir + "${basename - #{i}.#{extension}"
         
     | 
| 
       29 
31 
     | 
    
         
             
                    i += 1
         
     | 
| 
       30 
32 
     | 
    
         
             
                  end
         
     | 
| 
       31 
33 
     | 
    
         | 
    
        data/lib/fyodor/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: fyodor
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.3.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Rafael Cavalcanti
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2022-02-03 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: toml
         
     | 
| 
         @@ -39,7 +39,7 @@ dependencies: 
     | 
|
| 
       39 
39 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       40 
40 
     | 
    
         
             
                    version: '3.0'
         
     | 
| 
       41 
41 
     | 
    
         
             
            description: Parse Kindle clippings into markdown files
         
     | 
| 
       42 
     | 
    
         
            -
            email:  
     | 
| 
      
 42 
     | 
    
         
            +
            email: dev@rafaelc.org
         
     | 
| 
       43 
43 
     | 
    
         
             
            executables:
         
     | 
| 
       44 
44 
     | 
    
         
             
            - fyodor
         
     | 
| 
       45 
45 
     | 
    
         
             
            extensions: []
         
     | 
| 
         @@ -56,16 +56,16 @@ files: 
     | 
|
| 
       56 
56 
     | 
    
         
             
            - lib/fyodor/entry.rb
         
     | 
| 
       57 
57 
     | 
    
         
             
            - lib/fyodor/entry_parser.rb
         
     | 
| 
       58 
58 
     | 
    
         
             
            - lib/fyodor/library.rb
         
     | 
| 
       59 
     | 
    
         
            -
            - lib/fyodor/ 
     | 
| 
      
 59 
     | 
    
         
            +
            - lib/fyodor/output_generator.rb
         
     | 
| 
       60 
60 
     | 
    
         
             
            - lib/fyodor/output_writer.rb
         
     | 
| 
       61 
61 
     | 
    
         
             
            - lib/fyodor/stats_printer.rb
         
     | 
| 
       62 
62 
     | 
    
         
             
            - lib/fyodor/strings.rb
         
     | 
| 
       63 
63 
     | 
    
         
             
            - lib/fyodor/version.rb
         
     | 
| 
       64 
     | 
    
         
            -
            homepage: https:// 
     | 
| 
      
 64 
     | 
    
         
            +
            homepage: https://rafaelc.org/fyodor
         
     | 
| 
       65 
65 
     | 
    
         
             
            licenses:
         
     | 
| 
       66 
66 
     | 
    
         
             
            - GPL-3.0-only
         
     | 
| 
       67 
67 
     | 
    
         
             
            metadata:
         
     | 
| 
       68 
     | 
    
         
            -
              source_code_uri: https:// 
     | 
| 
      
 68 
     | 
    
         
            +
              source_code_uri: https://rafaelc.org/fyodor
         
     | 
| 
       69 
69 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       70 
70 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       71 
71 
     | 
    
         
             
            require_paths:
         
     | 
    
        data/lib/fyodor/md_generator.rb
    DELETED
    
    | 
         @@ -1,96 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "fyodor/strings"
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            module Fyodor
         
     | 
| 
       4 
     | 
    
         
            -
              class MdGenerator
         
     | 
| 
       5 
     | 
    
         
            -
                include Strings
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
                def initialize(book, config)
         
     | 
| 
       8 
     | 
    
         
            -
                  @book = book
         
     | 
| 
       9 
     | 
    
         
            -
                  @config = config
         
     | 
| 
       10 
     | 
    
         
            -
                end
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                def content
         
     | 
| 
       13 
     | 
    
         
            -
                  header + body + bookmarks
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                private
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                def header
         
     | 
| 
       20 
     | 
    
         
            -
                  return <<~EOF
         
     | 
| 
       21 
     | 
    
         
            -
                  # #{@book.title}
         
     | 
| 
       22 
     | 
    
         
            -
                  #{"by #{@book.author}" unless @book.author.to_s.empty?}
         
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
                  #{header_counts}
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                  EOF
         
     | 
| 
       27 
     | 
    
         
            -
                end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                def header_counts
         
     | 
| 
       30 
     | 
    
         
            -
                  output = ""
         
     | 
| 
       31 
     | 
    
         
            -
                  @book.count_types.each do |type, n|
         
     | 
| 
       32 
     | 
    
         
            -
                    output += "#{n} #{pluralize(type, n)}, " if n > 0
         
     | 
| 
       33 
     | 
    
         
            -
                  end
         
     | 
| 
       34 
     | 
    
         
            -
                  output.delete_suffix(", ")
         
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                def pluralize(type, n)
         
     | 
| 
       38 
     | 
    
         
            -
                  n == 1 ? SINGULAR[type] : PLURAL[type]
         
     | 
| 
       39 
     | 
    
         
            -
                end
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                def body
         
     | 
| 
       42 
     | 
    
         
            -
                  entries = @book.reject { |entry| entry.type == Entry::TYPE[:bookmark] }
         
     | 
| 
       43 
     | 
    
         
            -
                  entries.size == 0 ? "" : entries_render(entries)
         
     | 
| 
       44 
     | 
    
         
            -
                end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                def bookmarks
         
     | 
| 
       47 
     | 
    
         
            -
                  bookmarks = @book.select { |entry| entry.type == Entry::TYPE[:bookmark] }
         
     | 
| 
       48 
     | 
    
         
            -
                  bookmarks.size == 0 ? "" : entries_render(bookmarks, "Bookmarks")
         
     | 
| 
       49 
     | 
    
         
            -
                end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                def entries_render(entries, title=nil)
         
     | 
| 
       52 
     | 
    
         
            -
                  output = "---\n\n"
         
     | 
| 
       53 
     | 
    
         
            -
                  output += "## #{title}\n\n" unless title.nil?
         
     | 
| 
       54 
     | 
    
         
            -
                  entries.each do |entry|
         
     | 
| 
       55 
     | 
    
         
            -
                    output += "#{item_text(entry)}\n\n"
         
     | 
| 
       56 
     | 
    
         
            -
                    output += "<p style=\"text-align: right;\"><sup>#{item_desc(entry)}</sup></p>\n\n"
         
     | 
| 
       57 
     | 
    
         
            -
                  end
         
     | 
| 
       58 
     | 
    
         
            -
                  output
         
     | 
| 
       59 
     | 
    
         
            -
                end
         
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
                def item_text(entry)
         
     | 
| 
       62 
     | 
    
         
            -
                  case entry.type
         
     | 
| 
       63 
     | 
    
         
            -
                  when Entry::TYPE[:bookmark]
         
     | 
| 
       64 
     | 
    
         
            -
                    "* #{page(entry)}"
         
     | 
| 
       65 
     | 
    
         
            -
                  when Entry::TYPE[:note]
         
     | 
| 
       66 
     | 
    
         
            -
                    "* _Note:_\n#{entry.text.strip}"
         
     | 
| 
       67 
     | 
    
         
            -
                  else
         
     | 
| 
       68 
     | 
    
         
            -
                    "* #{entry.text.strip}"
         
     | 
| 
       69 
     | 
    
         
            -
                  end
         
     | 
| 
       70 
     | 
    
         
            -
                end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                def item_desc(entry)
         
     | 
| 
       73 
     | 
    
         
            -
                  return entry.desc unless entry.desc_parsed?
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
                  case entry.type
         
     | 
| 
       76 
     | 
    
         
            -
                  when Entry::TYPE[:bookmark]
         
     | 
| 
       77 
     | 
    
         
            -
                    time(entry)
         
     | 
| 
       78 
     | 
    
         
            -
                  else
         
     | 
| 
       79 
     | 
    
         
            -
                    (type(entry) + " @ " + page(entry) + " " + time(entry)).strip
         
     | 
| 
       80 
     | 
    
         
            -
                  end
         
     | 
| 
       81 
     | 
    
         
            -
                end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
                def page(entry)
         
     | 
| 
       84 
     | 
    
         
            -
                  ((entry.page.nil? ? "" : "page #{entry.page}, ") +
         
     | 
| 
       85 
     | 
    
         
            -
                    (entry.loc.nil? ? "" : "loc. #{entry.loc}")).delete_suffix(", ")
         
     | 
| 
       86 
     | 
    
         
            -
                end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
                def time(entry)
         
     | 
| 
       89 
     | 
    
         
            -
                  @config["time"] ? "[#{entry.time}]" : ""
         
     | 
| 
       90 
     | 
    
         
            -
                end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
                def type(entry)
         
     | 
| 
       93 
     | 
    
         
            -
                  SINGULAR[entry.type]
         
     | 
| 
       94 
     | 
    
         
            -
                end
         
     | 
| 
       95 
     | 
    
         
            -
              end
         
     | 
| 
       96 
     | 
    
         
            -
            end
         
     |