fyodor 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -14
- data/bin/fyodor +15 -4
- data/lib/fyodor/book.rb +0 -5
- data/lib/fyodor/config_getter.rb +7 -17
- data/lib/fyodor/entry.rb +1 -1
- data/lib/fyodor/output_generator.rb +9 -45
- data/lib/fyodor/output_writer.rb +27 -16
- data/lib/fyodor/strings.rb +15 -10
- data/lib/fyodor/version.rb +1 -1
- data/share/defaults/fyodor.toml +14 -0
- data/share/defaults/template.erb +20 -0
- data/share/docs/expected_desc.md +52 -0
- data/share/docs/input_demo/extract_pt-br.txt +175 -0
- data/share/docs/input_demo/multiline_notes.txt +14 -0
- data/share/docs/input_demo/page_only_and_lowercase.txt +25 -0
- data/share/docs/output_demo/Alan Harris, Konstantin Haase - Sinatra Up and Running.md +24 -0
- data/share/docs/output_demo/Sandi Metz - Practical Object-Oriented Design in Ruby.md +28 -0
- metadata +11 -4
- data/share/template.erb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 88047546f202ccab2251c4c6b1258cede3e051dc189543b184840c931d039b05
|
4
|
+
data.tar.gz: 33aa4298ddc3a369ca1e89cee791d2625447272e8bd6e28bf31ed342ec66bbf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 186dd430f5299c25b33bcf1baff234525cd186592f6702980d24753f0ff3a48943c21bf0b5c5601bf8dc86d3e826d261328f50d4225fade827eef259e86fb305
|
7
|
+
data.tar.gz: b03ee75159f0db45a1e55912b74de25f716534d009b19495e711648d16f3336eda1afbcfa566e689c9ff4c951cc371650a39ac217e34fc9619622aaab4bbcbf2
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Convert your Amazon Kindle highlights, notes and bookmarks into markdown (or any
|
|
6
6
|
|
7
7
|
This application parses `My Clippings.txt` from your Kindle and generates a markdown file for each book/document, in the format `#{Author} - #{Title}.md`. This way, your annotations are conveniently stored and easily managed.
|
8
8
|
|
9
|
-
[For samples of the output, click here.](docs/output_demo)
|
9
|
+
[For samples of the output, click here.](share/docs/output_demo)
|
10
10
|
|
11
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
|
|
@@ -20,6 +20,7 @@ To read more about the motivation and what problem it tries to solve, [check thi
|
|
20
20
|
- By default, output in a format that is clean and easy to edit/fiddle around: markdown.
|
21
21
|
- Bookmarks are placed together and notes are formatted differently, for better visualization.
|
22
22
|
- Entirely customizable output, in the format you prefer, through templates.
|
23
|
+
- Customizable file names.
|
23
24
|
|
24
25
|
This program is based on the clippings file generated by Kindle 2019, but should work with other models.
|
25
26
|
|
@@ -50,10 +51,10 @@ $ gem update fyodor
|
|
50
51
|
|
51
52
|
Fyodor reads an optional configuration file at `~/.config/fyodor/fyodor.toml` or `$XDG_CONFIG_HOME/fyodor/fyodor.toml`. This section describes the available parameters (none is required).
|
52
53
|
|
53
|
-
To download the [
|
54
|
+
To download the [default configuration](share/defaults/fyodor.toml):
|
54
55
|
|
55
56
|
```shell-session
|
56
|
-
$ curl https://raw.githubusercontent.com/rc2dev/fyodor/master/
|
57
|
+
$ curl https://raw.githubusercontent.com/rc2dev/fyodor/master/share/defaults/fyodor.toml --create-dirs -o ~/.config/fyodor/fyodor.toml
|
57
58
|
```
|
58
59
|
|
59
60
|
### Languages
|
@@ -75,23 +76,20 @@ page = "página"
|
|
75
76
|
time = "Adicionado:"
|
76
77
|
```
|
77
78
|
|
78
|
-
###
|
79
|
+
### Change output file names
|
79
80
|
|
80
|
-
|
81
|
+
By default, Fyodor writes the output files in the format `%{author_fill} - %{title}.md`. You can change that by setting `filename` under `[output]`. For example, for HTML extension and to only display the title of the book:
|
81
82
|
|
82
83
|
```toml
|
83
84
|
[output]
|
84
|
-
|
85
|
+
filename = "%{title}.html"
|
85
86
|
```
|
86
87
|
|
87
|
-
|
88
|
+
Available variables:
|
88
89
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
[output]
|
93
|
-
extension = "html"
|
94
|
-
```
|
90
|
+
- `%{author}`: Author of the book.
|
91
|
+
- `%{author_fill}`: Author of the book. If empty, shows "Author Not Available".
|
92
|
+
- `%{title}`: Title of the book.
|
95
93
|
|
96
94
|
## Templating
|
97
95
|
|
@@ -99,8 +97,9 @@ You may change the structure of the files output by Fyodor by providing your own
|
|
99
97
|
|
100
98
|
To do that, place a ERB template at `~/.config/fyodor/template.erb` or `$XDG_CONFIG_HOME/fyodor/template.erb` and Fyodor will use it automatically.
|
101
99
|
|
102
|
-
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).
|
100
|
+
The default template can be found [here](share/defaults/template.erb). You can use any method or attribute available [on this class](lib/fyodor/output_generator.rb).
|
103
101
|
|
102
|
+
If you use a format other than markdown, you'll want to change the files extension. To do this, refer to [the corresponding section](#change-output-file-names).
|
104
103
|
|
105
104
|
## Usage
|
106
105
|
|
data/bin/fyodor
CHANGED
@@ -35,10 +35,21 @@ module Fyodor
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def run
|
38
|
-
library = Library.new
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
@library = Library.new
|
39
|
+
|
40
|
+
ClippingsParser.new(@clippings_path, @config["parser"]).parse(@library)
|
41
|
+
StatsPrinter.new(@library).print
|
42
|
+
write_output
|
43
|
+
end
|
44
|
+
|
45
|
+
def write_output
|
46
|
+
return if @library.empty?
|
47
|
+
|
48
|
+
puts "\nWriting to #{@output_dir}..."
|
49
|
+
@output_dir.mkpath unless @output_dir.exist?
|
50
|
+
@library.each do |book|
|
51
|
+
OutputWriter.new(book, @output_dir, @config["output"]).write
|
52
|
+
end
|
42
53
|
end
|
43
54
|
|
44
55
|
def parse_args
|
data/lib/fyodor/book.rb
CHANGED
@@ -25,11 +25,6 @@ module Fyodor
|
|
25
25
|
@rej_dup += 1 if @entries.add?(entry).nil?
|
26
26
|
end
|
27
27
|
|
28
|
-
def basename
|
29
|
-
base = @author.to_s.empty? ? "Author N/A - #{@title}" : "#{@author} - #{@title}"
|
30
|
-
base.strip
|
31
|
-
end
|
32
|
-
|
33
28
|
def count_types
|
34
29
|
list = group_by(&:type).map { |k, v| [k, v.size] }
|
35
30
|
Hash[list]
|
data/lib/fyodor/config_getter.rb
CHANGED
@@ -4,29 +4,15 @@ require "toml"
|
|
4
4
|
|
5
5
|
module Fyodor
|
6
6
|
class ConfigGetter
|
7
|
-
|
7
|
+
DEFAULT_CONFIG_PATH = File.dirname(__FILE__) + "/../../share/defaults/fyodor.toml"
|
8
|
+
DEFAULT_TEMPLATE_PATH = File.dirname(__FILE__) + "/../../share/defaults/template.erb"
|
8
9
|
|
9
|
-
DEFAULT_CONFIG = {
|
10
|
-
"parser" => {
|
11
|
-
"highlight" => "Your Highlight",
|
12
|
-
"note" => "Your Note",
|
13
|
-
"bookmark" => "Your Bookmark",
|
14
|
-
"clip" => "Clip This Article",
|
15
|
-
"loc" => "Location",
|
16
|
-
"page" => "page",
|
17
|
-
"time" => "Added on"
|
18
|
-
},
|
19
|
-
"output" => {
|
20
|
-
"time" => false,
|
21
|
-
"extension" => "md"
|
22
|
-
}
|
23
|
-
}
|
24
10
|
|
25
11
|
def config
|
26
12
|
return @config if defined?(@config)
|
27
13
|
|
28
14
|
Hash.include CoreExtensions::Hash::Merging
|
29
|
-
config =
|
15
|
+
config = default_config.deep_merge(user_config)
|
30
16
|
config["output"]["template"] = template
|
31
17
|
|
32
18
|
@config = config
|
@@ -57,6 +43,10 @@ module Fyodor
|
|
57
43
|
{}
|
58
44
|
end
|
59
45
|
|
46
|
+
def default_config
|
47
|
+
@default_config ||= TOML.load_file(DEFAULT_CONFIG_PATH)
|
48
|
+
end
|
49
|
+
|
60
50
|
def template
|
61
51
|
if user_template_path.exist?
|
62
52
|
puts "Using custom template at #{user_template_path}.\n\n"
|
data/lib/fyodor/entry.rb
CHANGED
@@ -5,68 +5,32 @@ module Fyodor
|
|
5
5
|
class OutputGenerator
|
6
6
|
include Strings
|
7
7
|
|
8
|
-
def initialize(book, config)
|
8
|
+
def initialize(book, config, params={})
|
9
9
|
@book = book
|
10
10
|
@config = config
|
11
|
+
@params = params
|
11
12
|
end
|
12
13
|
|
13
|
-
def
|
14
|
-
ERB.new(@config["template"],
|
14
|
+
def output
|
15
|
+
ERB.new(@config["template"], trim_mode: '-').result(binding)
|
15
16
|
end
|
16
17
|
|
17
18
|
|
18
19
|
private
|
19
|
-
|
20
|
+
|
20
21
|
def regular_entries
|
21
|
-
@book.reject { |entry| entry.type == Entry::TYPE[:bookmark] }
|
22
|
+
@regular_entries ||= @book.reject { |entry| entry.type == Entry::TYPE[:bookmark] }.sort
|
22
23
|
end
|
23
24
|
|
24
25
|
def bookmarks
|
25
|
-
@book.select { |entry| entry.type == Entry::TYPE[:bookmark] }
|
26
|
-
end
|
27
|
-
|
28
|
-
def render_entries(entries)
|
29
|
-
output = ""
|
30
|
-
entries.sort.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
|
26
|
+
@bookmarks ||= @book.select { |entry| entry.type == Entry::TYPE[:bookmark] }.sort
|
35
27
|
end
|
36
28
|
|
37
|
-
def
|
38
|
-
|
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?
|
29
|
+
def place(entry)
|
30
|
+
raise "Description is not parsed." unless entry.desc_parsed?
|
50
31
|
|
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
32
|
((entry.page.nil? ? "" : "page #{entry.page}, ") +
|
61
33
|
(entry.loc.nil? ? "" : "loc. #{entry.loc}")).delete_suffix(", ")
|
62
34
|
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
35
|
end
|
72
36
|
end
|
data/lib/fyodor/output_writer.rb
CHANGED
@@ -1,37 +1,48 @@
|
|
1
1
|
require "fyodor/output_generator"
|
2
|
+
require "fyodor/strings"
|
3
|
+
require "pathname"
|
2
4
|
|
3
5
|
module Fyodor
|
4
6
|
class OutputWriter
|
5
|
-
|
6
|
-
|
7
|
+
include Strings
|
8
|
+
|
9
|
+
def initialize(book, output_dir, config)
|
10
|
+
@book = book
|
7
11
|
@output_dir = output_dir
|
8
|
-
@output_dir.mkdir unless @output_dir.exist?
|
9
12
|
@config = config
|
10
13
|
end
|
11
14
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
content = OutputGenerator.new(book, @config).content
|
16
|
-
File.open(path(book), "w") { |f| f.puts(content) }
|
17
|
-
end
|
15
|
+
def write
|
16
|
+
output = OutputGenerator.new(@book, @config).output
|
17
|
+
File.open(path, "w") { |f| f.puts(output) }
|
18
18
|
end
|
19
19
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
-
def
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
def filename
|
24
|
+
return @filename if defined?(@filename)
|
25
|
+
|
26
|
+
filename = @config["filename"] % {
|
27
|
+
author: @book.author,
|
28
|
+
author_fill: @book.author.empty? ? SINGULAR[:AUTHOR_NA] : @book.author,
|
29
|
+
title: @book.title
|
30
|
+
}
|
31
|
+
filename = filename.gsub(/[?*:|\/"<>]/,"_")
|
32
|
+
|
33
|
+
Pathname.new(filename)
|
34
|
+
end
|
35
|
+
|
36
|
+
def path
|
37
|
+
result = @output_dir + filename
|
27
38
|
|
28
39
|
i = 2
|
29
|
-
while(
|
30
|
-
|
40
|
+
while(result.exist?)
|
41
|
+
result = @output_dir + "#{filename.basename} - #{i}#{filename.extname}"
|
31
42
|
i += 1
|
32
43
|
end
|
33
44
|
|
34
|
-
|
45
|
+
result
|
35
46
|
end
|
36
47
|
end
|
37
48
|
end
|
data/lib/fyodor/strings.rb
CHANGED
@@ -2,16 +2,21 @@ require "fyodor/entry"
|
|
2
2
|
|
3
3
|
module Fyodor
|
4
4
|
module Strings
|
5
|
-
PLURAL = {
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
PLURAL = {
|
6
|
+
Entry::TYPE[:highlight] => "highlights",
|
7
|
+
Entry::TYPE[:note] => "notes",
|
8
|
+
Entry::TYPE[:bookmark] => "bookmarks",
|
9
|
+
Entry::TYPE[:clip] => "clips",
|
10
|
+
nil => "unrecognized"
|
11
|
+
}
|
10
12
|
|
11
|
-
SINGULAR = {
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
SINGULAR = {
|
14
|
+
Entry::TYPE[:highlight] => "highlight",
|
15
|
+
Entry::TYPE[:note] => "note",
|
16
|
+
Entry::TYPE[:bookmark] => "bookmark",
|
17
|
+
Entry::TYPE[:clip] => "clip",
|
18
|
+
nil => "unrecognized",
|
19
|
+
:AUTHOR_NA => "Author Not Available"
|
20
|
+
}
|
16
21
|
end
|
17
22
|
end
|
data/lib/fyodor/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Fyodor's default config.
|
2
|
+
|
3
|
+
# Set the translations you get on your clippings file.
|
4
|
+
[parser]
|
5
|
+
highlight = "Your Highlight"
|
6
|
+
note = "Your Note"
|
7
|
+
bookmark = "Your Bookmark"
|
8
|
+
clip = "Clip This Article"
|
9
|
+
loc = "Location"
|
10
|
+
page = "page"
|
11
|
+
time = "Added on"
|
12
|
+
|
13
|
+
[output]
|
14
|
+
filename = "%{author_fill} - %{title}.md"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%# Fyodor's default template. -%>
|
2
|
+
# <%= @book.author.empty? ? SINGULAR[:AUTHOR_NA] : @book.author %> - <%= @book.title %>
|
3
|
+
<% if regular_entries.size > 0 -%>
|
4
|
+
|
5
|
+
## Highlights and notes
|
6
|
+
<% for entry in regular_entries -%>
|
7
|
+
|
8
|
+
- <%= "_Note:_ " if entry.type == Entry::TYPE[:note] %><%= entry.text %>
|
9
|
+
|
10
|
+
<%= entry.desc_parsed? ? (SINGULAR[entry.type] + " @ " + place(entry)) : entry.desc %>
|
11
|
+
<% end -%>
|
12
|
+
<% end -%>
|
13
|
+
<% if bookmarks.size > 0 -%>
|
14
|
+
|
15
|
+
## Bookmarks
|
16
|
+
|
17
|
+
<% for bookmark in bookmarks -%>
|
18
|
+
- <%= bookmark.desc_parsed? ? place(bookmark) : bookmark.desc %>
|
19
|
+
<% end -%>
|
20
|
+
<% end -%>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Expected description syntax
|
2
|
+
|
3
|
+
Fyodor tries to parse entry descriptions. This allows tasks related to a cleaner output, such as:
|
4
|
+
|
5
|
+
- Ignore duplicate entries.
|
6
|
+
- Order entries by location/page.
|
7
|
+
- Render the description in a shorter and more elegant way.
|
8
|
+
- Render each type of entry differently.
|
9
|
+
|
10
|
+
The syntax depends on the user language and on characteristics of the book/document. In this document, I keep track of what I've found until the date and coded Fyodor to expect.
|
11
|
+
|
12
|
+
## Default - English
|
13
|
+
|
14
|
+
### Highlights
|
15
|
+
|
16
|
+
```
|
17
|
+
- Your Highlight on Location 2637-2637 | Added on Monday, Setember 16, 2019 9:50:16 AM
|
18
|
+
- Your Highlight at location 311-317 | Added on Tuesday, 13 May 2020 03:05:21
|
19
|
+
- Your Highlight on page 315 | Location 4444-4444 | Added on Monday, September 16, 2019 10:06:01 AM
|
20
|
+
- Your Highlight on page 21-21 | Added on Monday, 12 May 2020 11:01:03
|
21
|
+
```
|
22
|
+
|
23
|
+
### Notes
|
24
|
+
|
25
|
+
```
|
26
|
+
- Your Note on Location 2435 | Added on Monday, September...
|
27
|
+
- Your Note on page 315 | Location 4444 | Added on Monday, September 16, 2019 10:06:09 AM
|
28
|
+
```
|
29
|
+
|
30
|
+
### Bookmarks
|
31
|
+
|
32
|
+
```
|
33
|
+
- Your Bookmark on Location 2434 | Added on Monday...
|
34
|
+
- Your Bookmark on page 315 | Location 4444 | Added on Monday...
|
35
|
+
```
|
36
|
+
|
37
|
+
### Clips
|
38
|
+
|
39
|
+
```
|
40
|
+
- Clip This Article on Location 401 | Added on Monday...
|
41
|
+
```
|
42
|
+
|
43
|
+
## Locale pt-br
|
44
|
+
|
45
|
+
```
|
46
|
+
- Seu destaque ou posição 2309-2311 | Adicionado: domingo, 15 de setembro de 2019 12:40:37
|
47
|
+
- Seu destaque na página 70 | posição 952-953 | Adicionado: quinta-feira...
|
48
|
+
- Sua nota ou posição 2383 | Adicionado: ...
|
49
|
+
- Seu marcador ou posição 2637 | Adicionado: segunda-feira, 16 de setembro de 2019 11:47:02
|
50
|
+
- Seu marcador na página 315 | posição 4445 | Adicionado: segunda-feira, 16 de setembro de 2019 11:45:54
|
51
|
+
- Recortar este artigo na posição 401 | Adicionado: segunda-feira, 16 de setembro de 2019 11:44:35
|
52
|
+
```
|
@@ -0,0 +1,175 @@
|
|
1
|
+
Your P2K Articles (2019-11-01) (P2K)
|
2
|
+
- Seu destaque ou posição 77-80 | Adicionado: sábado, 2 de novembro de 2019 14:03:00
|
3
|
+
|
4
|
+
So my main advice to anyone preparing to give a talk on stage is to cut out everything from your talk that’s not surprising. (Nobody has ever complained that a talk was too short.) Use this rule in all your public writing. If you already found something surprising in what you’re presenting, then remove everything else. If you haven’t found something surprising about it yet, keep looking until you do.
|
5
|
+
==========
|
6
|
+
On Writing Well, 30th Anniversary Edition: An Informal Guide to Writing Nonfiction (Zinsser, William)
|
7
|
+
- Sua nota ou posição 115 | Adicionado: sábado, 2 de novembro de 2019 20:43:52
|
8
|
+
|
9
|
+
This is a note.
|
10
|
+
==========
|
11
|
+
On Writing Well, 30th Anniversary Edition: An Informal Guide to Writing Nonfiction (Zinsser, William)
|
12
|
+
- Seu destaque ou posição 295-297 | Adicionado: sábado, 2 de novembro de 2019 20:47:01
|
13
|
+
|
14
|
+
The point is that you have to strip your writing down before you can build it back up. You must know what the essential tools are and what job they were designed to do. Extending the metaphor of carpentry, it’s first necessary to be able to saw wood neatly and to drive nails. Later you can bevel the edges or add elegant finials, if that’s your taste.
|
15
|
+
==========
|
16
|
+
Your P2K Articles (2019-11-02) (P2K)
|
17
|
+
- Seu destaque ou posição 530-532 | Adicionado: sábado, 2 de novembro de 2019 21:20:24
|
18
|
+
|
19
|
+
If you are going to invest time in a class, certification, or degree make sure you’ll leave with skills that employers actually want, and don’t pay tons of money for something you could get for less.
|
20
|
+
==========
|
21
|
+
Your P2K Articles (2019-11-02) (P2K)
|
22
|
+
- Seu destaque ou posição 931-932 | Adicionado: sábado, 2 de novembro de 2019 21:22:48
|
23
|
+
|
24
|
+
Traits like speed, ambition, independence, bravery, and humor — they’re all relative. Back home I’m considered quiet. Here I’m considered loud.
|
25
|
+
==========
|
26
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
27
|
+
- Seu destaque ou posição 734-734 | Adicionado: sábado, 2 de novembro de 2019 21:36:32
|
28
|
+
|
29
|
+
At the coding level, we often need to have the same information represented in different forms.
|
30
|
+
==========
|
31
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
32
|
+
- Seu destaque ou posição 740-742 | Adicionado: sábado, 2 de novembro de 2019 21:37:38
|
33
|
+
|
34
|
+
Class definitions can be generated automatically from the online database schema, or from the metadata used to build the schema in the first place. The code extracts in this book are inserted by a preprocessor each time we format the text. The trick is to make the process active: this cannot be a one-time conversion, or we're back in a position of duplicating data.
|
35
|
+
==========
|
36
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
37
|
+
- Seu destaque ou posição 744-746 | Adicionado: sábado, 2 de novembro de 2019 21:38:56
|
38
|
+
|
39
|
+
The DRY principle tells us to keep the low-level knowledge in the code, where it belongs, and reserve the comments for other, high-level explanations. Otherwise, we're duplicating knowledge,
|
40
|
+
==========
|
41
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
42
|
+
- Seu destaque ou posição 749-751 | Adicionado: sábado, 2 de novembro de 2019 21:40:40
|
43
|
+
|
44
|
+
The documentation and code both contain representations of the same knowledge. And we all know that in the heat of the moment, with deadlines looming and important clients clamoring, we tend to defer the updating of documentation.
|
45
|
+
==========
|
46
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
47
|
+
- Seu destaque ou posição 755-756 | Adicionado: sábado, 2 de novembro de 2019 21:41:44
|
48
|
+
|
49
|
+
Many languages impose considerable duplication in the source.
|
50
|
+
==========
|
51
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
52
|
+
- Sua nota ou posição 756 | Adicionado: sábado, 2 de novembro de 2019 21:42:31
|
53
|
+
|
54
|
+
Diz que nao ha muito o que fazer. Cita as IDEs no caso de C.
|
55
|
+
==========
|
56
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
57
|
+
- Sua nota ou posição 754 | Adicionado: sábado, 2 de novembro de 2019 21:43:12
|
58
|
+
|
59
|
+
Única solução que ele menciona.
|
60
|
+
==========
|
61
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
62
|
+
- Seu destaque ou posição 764-765 | Adicionado: sábado, 2 de novembro de 2019 21:43:53
|
63
|
+
|
64
|
+
There is absolutely no point in duplicating a function or class header comment between the two files. Use the header files to document interface issues, and the implementation files to document the nitty-gritty details that users of your code don't need to know.
|
65
|
+
==========
|
66
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
67
|
+
- Seu destaque ou posição 767-767 | Adicionado: sábado, 2 de novembro de 2019 21:45:16
|
68
|
+
|
69
|
+
Sometimes, duplication comes about as the result of mistakes in the design.
|
70
|
+
==========
|
71
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
72
|
+
- Sua nota ou posição 767 | Adicionado: sábado, 2 de novembro de 2019 21:45:49
|
73
|
+
|
74
|
+
Dá como e exemplo a falta de normalização.
|
75
|
+
==========
|
76
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
77
|
+
- Seu destaque ou posição 779-781 | Adicionado: sábado, 2 de novembro de 2019 21:47:07
|
78
|
+
|
79
|
+
Later on in the development process, you may choose to violate the DRY principle for performance reasons. Frequently this occurs when you need to cache data to avoid repeating expensive operations. The trick is to localize the impact. The violation is not exposed to the outside world: only the methods within the class have to worry about keeping things straight.
|
80
|
+
==========
|
81
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
82
|
+
- Seu destaque ou posição 783-784 | Adicionado: sábado, 2 de novembro de 2019 21:50:13
|
83
|
+
|
84
|
+
Where possible, always use accessor functions to read and write the attributes of objects.[1] It will make it easier to add functionality, such as caching, in the future.
|
85
|
+
==========
|
86
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
87
|
+
- Sua nota ou posição 780 | Adicionado: sábado, 2 de novembro de 2019 21:51:09
|
88
|
+
|
89
|
+
Falando sobre ter start, end e lngth numa classe. Length deveria ser um atributo calculado, mas no futuro vc pode violar o dry e torna-lol um atributo como start e end por questoes de perflrmance (evitar o calculo repetido).
|
90
|
+
==========
|
91
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
92
|
+
- Seu destaque ou posição 785-787 | Adicionado: sábado, 2 de novembro de 2019 21:51:51
|
93
|
+
|
94
|
+
The use of accessor functions ties in with Meyer's Uniform Access principle [Mey97b], which states that "All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation."
|
95
|
+
==========
|
96
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
97
|
+
- Seu destaque ou posição 793-793 | Adicionado: sábado, 2 de novembro de 2019 21:52:53
|
98
|
+
|
99
|
+
You may well save some seconds now, but at the potential loss of hours later.
|
100
|
+
==========
|
101
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
102
|
+
- Sua nota ou posição 793 | Adicionado: sábado, 2 de novembro de 2019 21:53:25
|
103
|
+
|
104
|
+
Impatient duplication
|
105
|
+
==========
|
106
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
107
|
+
- Seu destaque ou posição 803-805 | Adicionado: sábado, 2 de novembro de 2019 21:54:49
|
108
|
+
|
109
|
+
Commonly needed functionality or data that doesn't fall into an obvious area of responsibility can get implemented many times over. We feel that the best way to deal with this is to encourage active and frequent communication between developers. Set up forums to discuss common problems.
|
110
|
+
==========
|
111
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
112
|
+
- Seu destaque ou posição 807-809 | Adicionado: sábado, 2 de novembro de 2019 21:55:57
|
113
|
+
|
114
|
+
Appoint a team member as the project librarian, whose job is to facilitate the exchange of knowledge. Have a central place in the source tree where utility routines and scripts can be deposited. And make a point of reading other people's source code and documentation, either informally or during code reviews.
|
115
|
+
==========
|
116
|
+
The Pragmatic Programmer: From Journeyman to Master (Andrew Hunt;David Thomas)
|
117
|
+
- Seu destaque ou posição 812-813 | Adicionado: sábado, 2 de novembro de 2019 21:56:23
|
118
|
+
|
119
|
+
What you're trying to do is foster an environment where it's easier to find and reuse existing stuff than to write it yourself. If it isn't easy, people won't do it.
|
120
|
+
==========
|
121
|
+
Crime and Punishment (AmazonClassics Edition) (Dostoyevsky, Fyodor)
|
122
|
+
- Seu destaque na página 467 | posição 6607-6609 | Adicionado: domingo, 3 de novembro de 2019 18:43:35
|
123
|
+
|
124
|
+
Sonia, timid by nature, had felt before that day that she could be ill-treated more easily than anyone, and that she could be wronged with impunity. Yet till that moment she had fancied that she might escape misfortune by care, gentleness and submissiveness before everyone.
|
125
|
+
==========
|
126
|
+
O Processo (Franz Kafka)
|
127
|
+
- Seu marcador ou posição 604 | Adicionado: segunda-feira, 11 de novembro de 2019 04:49:31
|
128
|
+
|
129
|
+
|
130
|
+
==========
|
131
|
+
Your P2K Articles (2019-11-10) (P2K)
|
132
|
+
- Seu destaque ou posição 67-67 | Adicionado: segunda-feira, 11 de novembro de 2019 18:58:31
|
133
|
+
|
134
|
+
Vamos a ser muy dueños de nuestro silencio y no esclavos de nuestras palabras.
|
135
|
+
==========
|
136
|
+
Your P2K Articles (2019-11-10) (P2K)
|
137
|
+
- Seu destaque ou posição 685-686 | Adicionado: segunda-feira, 11 de novembro de 2019 19:02:47
|
138
|
+
|
139
|
+
Though Protestant work ethic-driven Americans have tended to worry about the devil holding sway in idle time, it turns out idle time is crucial for creativity, innovation and breakthrough thinking.
|
140
|
+
==========
|
141
|
+
Your P2K Articles (2019-11-10) (P2K)
|
142
|
+
- Seu destaque ou posição 689-691 | Adicionado: segunda-feira, 11 de novembro de 2019 19:03:31
|
143
|
+
|
144
|
+
The default mode network is like a series of airport hubs in different and typically unconnected parts of the brain. And that's why it's so crucial. When the brain flips into idle mode, this network subconsciously puts together stray thoughts, makes seemingly random connections and enables us to see an old problem in an entirely new light.
|
145
|
+
==========
|
146
|
+
Your P2K Articles (2019-11-10) (P2K)
|
147
|
+
- Seu destaque ou posição 697-698 | Adicionado: segunda-feira, 11 de novembro de 2019 19:04:17
|
148
|
+
|
149
|
+
"To be most creative, you need this oscillation between deep study with focused attention and daydreaming, which is why you may have your great ideas when you're in the shower," Smart told me.
|
150
|
+
==========
|
151
|
+
Your P2K Articles (2019-11-10) (P2K)
|
152
|
+
- Seu destaque ou posição 699-700 | Adicionado: segunda-feira, 11 de novembro de 2019 19:04:38
|
153
|
+
|
154
|
+
Smart himself typically takes long, leisurely walks during the workday and carries a notebook with him to capture any interesting thoughts or ideas that his default mode network may burble to the surface.
|
155
|
+
==========
|
156
|
+
Your P2K Articles (2019-11-10) (P2K)
|
157
|
+
- Seu destaque ou posição 517-520 | Adicionado: segunda-feira, 11 de novembro de 2019 19:59:50
|
158
|
+
|
159
|
+
For those of you quick to point out that not making a decision is basically the same as not inviting the person (as they don’t get invited either way) that is true factually but not psychologically. Unmade decisions can be sources of distraction and stress and the more of them hover over us, they more we are burdening ourselves unnecessarily.
|
160
|
+
==========
|
161
|
+
Book without author
|
162
|
+
- Seu destaque ou posição 527-529 | Adicionado: segunda-feira, 11 de novembro de 2019 20:01:05
|
163
|
+
|
164
|
+
When dealing with non-urgent decisions, either impose an artificial deadline for making the decision or if you feel unready to do so, decide to defer the decision to a later (specific) date when you will revisit the issue (so it doesn’t hover over you as an outstanding task).
|
165
|
+
==========
|
166
|
+
Book without author
|
167
|
+
- Seu marcador ou posição 604 | Adicionado: segunda-feira, 11 de novembro de 2019 04:49:31
|
168
|
+
|
169
|
+
|
170
|
+
==========
|
171
|
+
Book without author
|
172
|
+
- Seu marcador ou posição 535 | Adicionado: segunda-feira, 11 de novembro de 2019 20:03:05
|
173
|
+
|
174
|
+
|
175
|
+
==========
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Harry Potter e il Prigioniero di Azkaban (Rowling, J.K.)
|
2
|
+
- Your Note at location 5170 | Added on Wednesday, 13 May 2020 20:55:46
|
3
|
+
|
4
|
+
This
|
5
|
+
is
|
6
|
+
a
|
7
|
+
test
|
8
|
+
note
|
9
|
+
==========
|
10
|
+
Harry Potter e il Prigioniero di Azkaban (Rowling, J.K.)
|
11
|
+
- Your Highlight at location 5170-5170 | Added on Wednesday, 13 May 2020 20:55:46
|
12
|
+
|
13
|
+
all’espressione
|
14
|
+
==========
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Kindle Paperwhite User’s Guide, 7th Edition (Amazon)
|
2
|
+
- Your Highlight at location 525-528 | Added on Monday, 11 May 2020 01:09:56
|
3
|
+
|
4
|
+
To highlight over to the next page, drag your finger to the bottom-right corner of the screen and the page will turn. You can highlight across multiple pages by continuing to drag your finger to the bottom-right corner of the screen. To highlight to the previous page, drag your finger to the top-left corner of the screen and the page will turn. You can highlight across multiple pages by continuing to drag your finger to the top-left corner of the screen.
|
5
|
+
==========
|
6
|
+
Rutherford 1996 - Of Birds and Gifts
|
7
|
+
- Your Highlight on page 13-13 | Added on Monday, 11 May 2020 15:08:37
|
8
|
+
|
9
|
+
interiorized form of repression" that New Order's hold on its Javanese subjects. A logic borne of tions and complicities incites an obsessional devotion to the idea of Javanese culture-a decidedly modern obsession shared by ers, researchers, and foreign guests (
|
10
|
+
==========
|
11
|
+
Brubaker 2004 - Ethnicity without groups
|
12
|
+
- Your Highlight on page 75-75 | Added on Tuesday, 12 May 2020 01:12:02
|
13
|
+
|
14
|
+
Even when census categories are initially remote from prevailing self-understandings, they may be taken up by cultural and political entrepreneurs and eventually reshape lines of identification (Starr 1987; Nagel 1995; Petersen 1987, 1997). Especially when they are linked through public policy to tangible benefits, official census categories can have the effect of "making up people" (Hacking 1986), or "nominating into existence" (Goldberg 1997: 29-30) new kinds of persons for individuals to be. Such categories, Goldberg argues from a Foucauldian perspective, are central to the state's exercise of "racial governmentality": censuses have comprised a "formative governmental technology in the service of the state to fashion racialized knowledgeto articulate categories, to gather data, and to put them to work" (Goldberg 1997: 30)
|
15
|
+
==========
|
16
|
+
Dangerous Visions (S.F. MASTERWORKS) (Ellison, Harlan)
|
17
|
+
- Your Highlight on page 27 | location 1097-1099 | Added on Tuesday, 12 May 2020 20:35:14
|
18
|
+
|
19
|
+
Or even if they weren’t animals, exactly. When he found out how many reservations were coming in over the teletype he realized that some people did in fact care. However, Mr. Mandala didn’t take much interest in things like that.
|
20
|
+
==========
|
21
|
+
The Early Works of F. Scott Fitzgerald (With Active Table of Contents) (Fitzgerald, F. Scott)
|
22
|
+
- Your Highlight at location 77-80 | Added on Tuesday, 12 May 2020 20:43:37
|
23
|
+
|
24
|
+
But Beatrice Blaine! There was a woman! Early pictures taken on her father’s estate at Lake Geneva, Wisconsin, or in Rome at the Sacred Heart Convent—an educational extravagance that in her youth was only for the daughters of the exceptionally wealthy—showed the exquisite delicacy of her features, the consummate art and simplicity of her clothes.
|
25
|
+
==========
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Alan Harris, Konstantin Haase - Sinatra: Up and Running
|
2
|
+
|
3
|
+
## Highlights and notes
|
4
|
+
|
5
|
+
- At a high-level, a domain-specific language is one that is dedicated to solving a particular type of problem. For example, SQL (structured query language) is designed to facilitate interaction with relational database systems. By contrast, a general-purpose language such as Ruby can be used to write code in many different domains.
|
6
|
+
|
7
|
+
highlight @ page 8, loc. 111-113
|
8
|
+
|
9
|
+
- Sinatra is not a framework; you’ll find no built-in ORM (object-relational mapper) tools, no pre-fab configuration files...you won’t even get a project folder unless you create one yourself.
|
10
|
+
|
11
|
+
highlight @ page 9, loc. 130-131
|
12
|
+
|
13
|
+
- Sinatra does not force you to adhere to the model-view-controller pattern, or any other pattern for that matter. It is a lightweight wrapper around Rack middleware
|
14
|
+
|
15
|
+
highlight @ page 9, loc. 135-136
|
16
|
+
|
17
|
+
- Who’s Using It? GitHub, Heroku, BBC, thoughtbot, Songbird, Engine Yard, and many others are active users of Sinatra in production environments.
|
18
|
+
|
19
|
+
highlight @ page 10, loc. 144-146
|
20
|
+
|
21
|
+
## Bookmarks
|
22
|
+
|
23
|
+
- page 84, loc. 1150
|
24
|
+
- page 315, loc. 4445
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Sandi Metz - Practical Object-Oriented Design in Ruby: An Agile Primer
|
2
|
+
|
3
|
+
## Highlights and notes
|
4
|
+
|
5
|
+
- One of the core truisms of software development is that as your code grows and requirements for the system that you are building change, additional logic will be added that is not yet present in the current system. In almost all cases, maintainability over the life of the code is more important than optimizing its present state.
|
6
|
+
|
7
|
+
highlight @ loc. 271-274
|
8
|
+
|
9
|
+
- The promise of using object-oriented (OO) design is that your code will be easier to maintain and evolve than otherwise.
|
10
|
+
|
11
|
+
highlight @ loc. 274-275
|
12
|
+
|
13
|
+
- This book uses Ruby to teach OOD but you do not need to know Ruby to understand the concepts herein.
|
14
|
+
|
15
|
+
highlight @ loc. 316-316
|
16
|
+
|
17
|
+
- every concept in this book can be directly translated to a statically typed OO language.
|
18
|
+
|
19
|
+
highlight @ loc. 319-320
|
20
|
+
|
21
|
+
- _Note:_ This is a note.
|
22
|
+
|
23
|
+
note @ loc. 1827
|
24
|
+
|
25
|
+
## Bookmarks
|
26
|
+
|
27
|
+
- loc. 1150
|
28
|
+
- loc. 4445
|
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.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rafael Cavalcanti
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-02-
|
11
|
+
date: 2022-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: toml
|
@@ -61,7 +61,14 @@ files:
|
|
61
61
|
- lib/fyodor/stats_printer.rb
|
62
62
|
- lib/fyodor/strings.rb
|
63
63
|
- lib/fyodor/version.rb
|
64
|
-
- share/
|
64
|
+
- share/defaults/fyodor.toml
|
65
|
+
- share/defaults/template.erb
|
66
|
+
- share/docs/expected_desc.md
|
67
|
+
- share/docs/input_demo/extract_pt-br.txt
|
68
|
+
- share/docs/input_demo/multiline_notes.txt
|
69
|
+
- share/docs/input_demo/page_only_and_lowercase.txt
|
70
|
+
- share/docs/output_demo/Alan Harris, Konstantin Haase - Sinatra Up and Running.md
|
71
|
+
- share/docs/output_demo/Sandi Metz - Practical Object-Oriented Design in Ruby.md
|
65
72
|
homepage: https://rafaelc.org/fyodor
|
66
73
|
licenses:
|
67
74
|
- GPL-3.0-only
|
@@ -75,7 +82,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
75
82
|
requirements:
|
76
83
|
- - ">="
|
77
84
|
- !ruby/object:Gem::Version
|
78
|
-
version: '2.
|
85
|
+
version: '2.7'
|
79
86
|
- - "<"
|
80
87
|
- !ruby/object:Gem::Version
|
81
88
|
version: '4'
|
data/share/template.erb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
<%# Fyodor's default template. -%>
|
2
|
-
# <%= @book.basename %>
|
3
|
-
|
4
|
-
## Highlights and notes
|
5
|
-
|
6
|
-
<% if regular_entries.size > 0 -%>
|
7
|
-
<%= render_entries(regular_entries) %>
|
8
|
-
<% else -%>
|
9
|
-
None.
|
10
|
-
<% end -%>
|
11
|
-
|
12
|
-
<% if bookmarks.size > 0 -%>
|
13
|
-
## Bookmarks
|
14
|
-
|
15
|
-
<%= render_entries(bookmarks) %>
|
16
|
-
<% end -%>
|