bridgetown_writebook 0.1.0 → 0.1.0.2
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/.idea/.gitignore +8 -0
- data/.idea/bridgetown_writebook.iml +111 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +7 -0
- data/bridgetown.automation.rb +21 -2
- data/lib/bridgetown_writebook/builder.rb +4 -0
- data/lib/bridgetown_writebook/commands/book.rb +83 -0
- data/lib/bridgetown_writebook/commands/chapter.rb +47 -0
- data/lib/bridgetown_writebook/commands.rb +15 -0
- data/lib/bridgetown_writebook/models/book.rb +92 -0
- data/lib/bridgetown_writebook/models/chapter.rb +62 -0
- data/lib/bridgetown_writebook/models/something.rb +63 -0
- data/lib/bridgetown_writebook/version.rb +1 -1
- data/lib/bridgetown_writebook.rb +1 -0
- metadata +12 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 706790ac167218b2e3e12b4765c83d2e3868a9b0fc0b8635af7e5937234415b1
|
|
4
|
+
data.tar.gz: 662a770b9c397cf80b0e69a2681d04f9214becd91ceadf01187d924c8c17e11e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b3541f4eb36f74d64154d0135dca1db9db45ba50242d27e5a6dab171104fbea56ce855c8000f5f166276b342f90251da1b8b200e54e1322058347656baf0094d
|
|
7
|
+
data.tar.gz: 3d5aa8046824c16b3d4cea27298214270d65b301267d2ca755f7093379575903d729e3b75f84784723f6902615efa43886414cac7dc57defb159a184194bd53d
|
data/.idea/.gitignore
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
|
3
|
+
<component name="ModuleRunConfigurationManager">
|
|
4
|
+
<shared />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="NewModuleRootManager">
|
|
7
|
+
<content url="file://$MODULE_DIR$" />
|
|
8
|
+
<orderEntry type="jdk" jdkName="asdf: 3.3.3" jdkType="RUBY_SDK" />
|
|
9
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
10
|
+
<orderEntry type="library" scope="PROVIDED" name="activemodel (v7.2.2.2, asdf: 3.3.3) [gem]" level="application" />
|
|
11
|
+
<orderEntry type="library" scope="PROVIDED" name="activesupport (v7.2.2.2, asdf: 3.3.3) [gem]" level="application" />
|
|
12
|
+
<orderEntry type="library" scope="PROVIDED" name="addressable (v2.8.7, asdf: 3.3.3) [gem]" level="application" />
|
|
13
|
+
<orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.8.1, asdf: 3.3.3) [gem]" level="application" />
|
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="ansi (v1.5.0, asdf: 3.3.3) [gem]" level="application" />
|
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.3, asdf: 3.3.3) [gem]" level="application" />
|
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="base64 (v0.3.0, asdf: 3.3.3) [gem]" level="application" />
|
|
17
|
+
<orderEntry type="library" scope="PROVIDED" name="benchmark (v0.4.1, asdf: 3.3.3) [gem]" level="application" />
|
|
18
|
+
<orderEntry type="library" scope="PROVIDED" name="bigdecimal (v3.2.2, asdf: 3.3.3) [gem]" level="application" />
|
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="bridgetown (v1.3.4, asdf: 3.3.3) [gem]" level="application" />
|
|
20
|
+
<orderEntry type="library" scope="PROVIDED" name="bridgetown-builder (v1.3.4, asdf: 3.3.3) [gem]" level="application" />
|
|
21
|
+
<orderEntry type="library" scope="PROVIDED" name="bridgetown-core (v1.3.4, asdf: 3.3.3) [gem]" level="application" />
|
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="bridgetown-paginate (v1.3.4, asdf: 3.3.3) [gem]" level="application" />
|
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="builder (v3.3.0, asdf: 3.3.3) [gem]" level="application" />
|
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.7.1, asdf: 3.3.3) [gem]" level="application" />
|
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="colorator (v1.1.0, asdf: 3.3.3) [gem]" level="application" />
|
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.3.5, asdf: 3.3.3) [gem]" level="application" />
|
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="connection_pool (v2.5.3, asdf: 3.3.3) [gem]" level="application" />
|
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="csv (v3.3.5, asdf: 3.3.3) [gem]" level="application" />
|
|
29
|
+
<orderEntry type="library" scope="PROVIDED" name="drb (v2.2.3, asdf: 3.3.3) [gem]" level="application" />
|
|
30
|
+
<orderEntry type="library" scope="PROVIDED" name="erubi (v1.13.1, asdf: 3.3.3) [gem]" level="application" />
|
|
31
|
+
<orderEntry type="library" scope="PROVIDED" name="faraday (v2.13.4, asdf: 3.3.3) [gem]" level="application" />
|
|
32
|
+
<orderEntry type="library" scope="PROVIDED" name="faraday-follow_redirects (v0.3.0, asdf: 3.3.3) [gem]" level="application" />
|
|
33
|
+
<orderEntry type="library" scope="PROVIDED" name="faraday-net_http (v3.4.1, asdf: 3.3.3) [gem]" level="application" />
|
|
34
|
+
<orderEntry type="library" scope="PROVIDED" name="ffi (v1.17.2, asdf: 3.3.3) [gem]" level="application" />
|
|
35
|
+
<orderEntry type="library" scope="PROVIDED" name="hash_with_dot_access (v1.2.0, asdf: 3.3.3) [gem]" level="application" />
|
|
36
|
+
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.14.7, asdf: 3.3.3) [gem]" level="application" />
|
|
37
|
+
<orderEntry type="library" scope="PROVIDED" name="json (v2.13.2, asdf: 3.3.3) [gem]" level="application" />
|
|
38
|
+
<orderEntry type="library" scope="PROVIDED" name="kramdown (v2.5.1, asdf: 3.3.3) [gem]" level="application" />
|
|
39
|
+
<orderEntry type="library" scope="PROVIDED" name="kramdown-parser-gfm (v1.1.0, asdf: 3.3.3) [gem]" level="application" />
|
|
40
|
+
<orderEntry type="library" scope="PROVIDED" name="language_server-protocol (v3.17.0.5, asdf: 3.3.3) [gem]" level="application" />
|
|
41
|
+
<orderEntry type="library" scope="PROVIDED" name="lint_roller (v1.1.0, asdf: 3.3.3) [gem]" level="application" />
|
|
42
|
+
<orderEntry type="library" scope="PROVIDED" name="liquid (v5.4.0, asdf: 3.3.3) [gem]" level="application" />
|
|
43
|
+
<orderEntry type="library" scope="PROVIDED" name="listen (v3.9.0, asdf: 3.3.3) [gem]" level="application" />
|
|
44
|
+
<orderEntry type="library" scope="PROVIDED" name="logger (v1.7.0, asdf: 3.3.3) [gem]" level="application" />
|
|
45
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.25.5, asdf: 3.3.3) [gem]" level="application" />
|
|
46
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest-profile (v0.0.2, asdf: 3.3.3) [gem]" level="application" />
|
|
47
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest-reporters (v1.7.1, asdf: 3.3.3) [gem]" level="application" />
|
|
48
|
+
<orderEntry type="library" scope="PROVIDED" name="net-http (v0.6.0, asdf: 3.3.3) [gem]" level="application" />
|
|
49
|
+
<orderEntry type="library" scope="PROVIDED" name="parallel (v1.27.0, asdf: 3.3.3) [gem]" level="application" />
|
|
50
|
+
<orderEntry type="library" scope="PROVIDED" name="parser (v3.3.9.0, asdf: 3.3.3) [gem]" level="application" />
|
|
51
|
+
<orderEntry type="library" scope="PROVIDED" name="prism (v1.4.0, asdf: 3.3.3) [gem]" level="application" />
|
|
52
|
+
<orderEntry type="library" scope="PROVIDED" name="public_suffix (v6.0.2, asdf: 3.3.3) [gem]" level="application" />
|
|
53
|
+
<orderEntry type="library" scope="PROVIDED" name="racc (v1.8.1, asdf: 3.3.3) [gem]" level="application" />
|
|
54
|
+
<orderEntry type="library" scope="PROVIDED" name="rack (v3.2.0, asdf: 3.3.3) [gem]" level="application" />
|
|
55
|
+
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, asdf: 3.3.3) [gem]" level="application" />
|
|
56
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v13.3.0, asdf: 3.3.3) [gem]" level="application" />
|
|
57
|
+
<orderEntry type="library" scope="PROVIDED" name="rb-fsevent (v0.11.2, asdf: 3.3.3) [gem]" level="application" />
|
|
58
|
+
<orderEntry type="library" scope="PROVIDED" name="rb-inotify (v0.11.1, asdf: 3.3.3) [gem]" level="application" />
|
|
59
|
+
<orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.11.2, asdf: 3.3.3) [gem]" level="application" />
|
|
60
|
+
<orderEntry type="library" scope="PROVIDED" name="rexml (v3.4.2, asdf: 3.3.3) [gem]" level="application" />
|
|
61
|
+
<orderEntry type="library" scope="PROVIDED" name="roda (v3.95.0, asdf: 3.3.3) [gem]" level="application" />
|
|
62
|
+
<orderEntry type="library" scope="PROVIDED" name="rouge (v4.6.0, asdf: 3.3.3) [gem]" level="application" />
|
|
63
|
+
<orderEntry type="library" scope="PROVIDED" name="rubocop (v1.80.0, asdf: 3.3.3) [gem]" level="application" />
|
|
64
|
+
<orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.46.0, asdf: 3.3.3) [gem]" level="application" />
|
|
65
|
+
<orderEntry type="library" scope="PROVIDED" name="rubocop-bridgetown (v0.6.1, asdf: 3.3.3) [gem]" level="application" />
|
|
66
|
+
<orderEntry type="library" scope="PROVIDED" name="rubocop-performance (v1.25.0, asdf: 3.3.3) [gem]" level="application" />
|
|
67
|
+
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.13.0, asdf: 3.3.3) [gem]" level="application" />
|
|
68
|
+
<orderEntry type="library" scope="PROVIDED" name="securerandom (v0.4.1, asdf: 3.3.3) [gem]" level="application" />
|
|
69
|
+
<orderEntry type="library" scope="PROVIDED" name="serbea (v1.0.1, asdf: 3.3.3) [gem]" level="application" />
|
|
70
|
+
<orderEntry type="library" scope="PROVIDED" name="thor (v1.4.0, asdf: 3.3.3) [gem]" level="application" />
|
|
71
|
+
<orderEntry type="library" scope="PROVIDED" name="tilt (v2.6.1, asdf: 3.3.3) [gem]" level="application" />
|
|
72
|
+
<orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.6, asdf: 3.3.3) [gem]" level="application" />
|
|
73
|
+
<orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v3.1.5, asdf: 3.3.3) [gem]" level="application" />
|
|
74
|
+
<orderEntry type="library" scope="PROVIDED" name="unicode-emoji (v4.0.4, asdf: 3.3.3) [gem]" level="application" />
|
|
75
|
+
<orderEntry type="library" scope="PROVIDED" name="uri (v1.0.3, asdf: 3.3.3) [gem]" level="application" />
|
|
76
|
+
<orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.7.3, asdf: 3.3.3) [gem]" level="application" />
|
|
77
|
+
</component>
|
|
78
|
+
<component name="RakeTasksCache-v2">
|
|
79
|
+
<option name="myRootTask">
|
|
80
|
+
<RakeTaskImpl id="rake">
|
|
81
|
+
<subtasks>
|
|
82
|
+
<RakeTaskImpl description="Build bridgetown_writebook-0.1.0.gem into the pkg directory" fullCommand="build" id="build" />
|
|
83
|
+
<RakeTaskImpl id="build">
|
|
84
|
+
<subtasks>
|
|
85
|
+
<RakeTaskImpl description="Generate SHA512 checksum of bridgetown_writebook-0.1.0.gem into the checksums directory" fullCommand="build:checksum" id="checksum" />
|
|
86
|
+
</subtasks>
|
|
87
|
+
</RakeTaskImpl>
|
|
88
|
+
<RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
|
|
89
|
+
<RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
|
|
90
|
+
<RakeTaskImpl description="Build and install bridgetown_writebook-0.1.0.gem into system gems" fullCommand="install" id="install" />
|
|
91
|
+
<RakeTaskImpl id="install">
|
|
92
|
+
<subtasks>
|
|
93
|
+
<RakeTaskImpl description="Build and install bridgetown_writebook-0.1.0.gem into system gems without network access" fullCommand="install:local" id="local" />
|
|
94
|
+
</subtasks>
|
|
95
|
+
</RakeTaskImpl>
|
|
96
|
+
<RakeTaskImpl description="Create tag v0.1.0 and build and push bridgetown_writebook-0.1.0.gem to rubygems.org" fullCommand="release[remote]" id="release[remote]" />
|
|
97
|
+
<RakeTaskImpl description="Run tests" fullCommand="test" id="test" />
|
|
98
|
+
<RakeTaskImpl description="" fullCommand="default" id="default" />
|
|
99
|
+
<RakeTaskImpl description="" fullCommand="release" id="release" />
|
|
100
|
+
<RakeTaskImpl id="release">
|
|
101
|
+
<subtasks>
|
|
102
|
+
<RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
|
|
103
|
+
<RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
|
|
104
|
+
<RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
|
|
105
|
+
</subtasks>
|
|
106
|
+
</RakeTaskImpl>
|
|
107
|
+
</subtasks>
|
|
108
|
+
</RakeTaskImpl>
|
|
109
|
+
</option>
|
|
110
|
+
</component>
|
|
111
|
+
</module>
|
data/.idea/modules.xml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/bridgetown_writebook.iml" filepath="$PROJECT_DIR$/.idea/bridgetown_writebook.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
data/.idea/vcs.xml
ADDED
data/bridgetown.automation.rb
CHANGED
|
@@ -50,8 +50,27 @@
|
|
|
50
50
|
#
|
|
51
51
|
# Read the Automations documentation: https://www.bridgetownrb.com/docs/automations
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
if File.exist?("config/boot.rb")
|
|
54
|
+
append_to_file "config/boot.rb" do
|
|
55
|
+
<<~RUBY
|
|
56
|
+
|
|
57
|
+
require "bridgetown_writebook/commands"
|
|
58
|
+
RUBY
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
create_file "config/boot.rb" do
|
|
62
|
+
<<~RUBY
|
|
63
|
+
# frozen_string_literal: true
|
|
64
|
+
|
|
65
|
+
require "bridgetown_writebook/commands"
|
|
66
|
+
RUBY
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
create_file "config/boot.rb" do
|
|
54
71
|
<<~RUBY
|
|
72
|
+
# frozen_string_literal: true
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
require "bridgetown_writebook/commands"
|
|
75
|
+
RUBY
|
|
57
76
|
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_all "bridgetown-core/commands/concerns"
|
|
4
|
+
require_relative "chapter"
|
|
5
|
+
|
|
6
|
+
module BridgetownWritebook
|
|
7
|
+
module Commands
|
|
8
|
+
class Book < Thor
|
|
9
|
+
desc "setup", "Setup folders and files for books"
|
|
10
|
+
def setup
|
|
11
|
+
create_books_folder
|
|
12
|
+
add_books_collection_to_config
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc "new", "Create a new book"
|
|
16
|
+
option :title, type: :string, required: true, desc: "Title of the book"
|
|
17
|
+
def new
|
|
18
|
+
title = options[:title]
|
|
19
|
+
folder_path = File.join("src", "_books", title.parameterize)
|
|
20
|
+
|
|
21
|
+
if Dir.exist?(folder_path)
|
|
22
|
+
Bridgetown.logger.info "Folder already exists: #{folder_path}"
|
|
23
|
+
else
|
|
24
|
+
FileUtils.mkdir_p(folder_path)
|
|
25
|
+
Bridgetown.logger.info "Folder created: #{folder_path}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
file_path = File.join(folder_path, "00-meta.md")
|
|
29
|
+
content = <<~MARKDOWN
|
|
30
|
+
---
|
|
31
|
+
title: #{text title}
|
|
32
|
+
subtitle:
|
|
33
|
+
authors: [ ]
|
|
34
|
+
---
|
|
35
|
+
MARKDOWN
|
|
36
|
+
|
|
37
|
+
File.write(file_path, content)
|
|
38
|
+
Bridgetown.logger.info "Creating a new book with title: #{title}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Register Chapters as a nested subcommand
|
|
42
|
+
desc "chapters <command>", "Manage chapters of a book"
|
|
43
|
+
subcommand "chapters", Chapter
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def create_books_folder
|
|
48
|
+
folder_path = File.join("src", "_books")
|
|
49
|
+
|
|
50
|
+
if Dir.exist?(folder_path)
|
|
51
|
+
Bridgetown.logger.info "Folder already exists: #{folder_path}"
|
|
52
|
+
else
|
|
53
|
+
FileUtils.mkdir_p(folder_path)
|
|
54
|
+
Bridgetown.logger.info "Folder created: #{folder_path}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def add_books_collection_to_config
|
|
59
|
+
config_file = "bridgetown.config.yml"
|
|
60
|
+
unless File.exist?(config_file)
|
|
61
|
+
Bridgetown.logger.info "Config file not found: #{config_file}"
|
|
62
|
+
return
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
content = File.read(config_file)
|
|
66
|
+
if content.include?("books:")
|
|
67
|
+
Bridgetown.logger.info "'books' collection already exists, skipping..."
|
|
68
|
+
return
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
config = YAML.load_file(config_file) || {}
|
|
72
|
+
config["collections"] ||= {}
|
|
73
|
+
config["collections"]["books"] = {
|
|
74
|
+
"output" => true,
|
|
75
|
+
"permalink" => "/books/:path/",
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
File.write(config_file, config.to_yaml)
|
|
79
|
+
Bridgetown.logger.info "'books' collection added/updated in #{config_file}"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgetownWritebook
|
|
4
|
+
module Commands
|
|
5
|
+
class Chapter < Thor
|
|
6
|
+
desc "add", "Add a new chapter to a book"
|
|
7
|
+
option :book, type: :string, required: true, desc: "Title of the book"
|
|
8
|
+
option :title, type: :string, required: true, desc: "Title of the chapter"
|
|
9
|
+
def add
|
|
10
|
+
book_title = options[:book]
|
|
11
|
+
chapter_title = options[:title]
|
|
12
|
+
@folder_path = File.join("src", "_books", book_title.parameterize)
|
|
13
|
+
|
|
14
|
+
unless Dir.exist?(@folder_path)
|
|
15
|
+
Bridgetown.logger.info "Book not found: #{book_title}"
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
chapter_file = File.join(@folder_path, "#{new_chapter_number}-#{chapter_title.parameterize}.md")
|
|
20
|
+
|
|
21
|
+
content = <<~MARKDOWN
|
|
22
|
+
---
|
|
23
|
+
title: #{text chapter_title}
|
|
24
|
+
---
|
|
25
|
+
MARKDOWN
|
|
26
|
+
|
|
27
|
+
File.write(chapter_file, content)
|
|
28
|
+
Bridgetown.logger.info "Chapter created: #{chapter_file}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def new_chapter_number
|
|
34
|
+
existing_chapters = Dir.children(@folder_path)
|
|
35
|
+
.grep(%r{^\d{2}-.*\.md$})
|
|
36
|
+
.sort
|
|
37
|
+
last_number = if existing_chapters.empty?
|
|
38
|
+
0
|
|
39
|
+
else
|
|
40
|
+
existing_chapters.last.split("-").first.to_i
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
format("%02d", last_number + 1)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_all "bridgetown-core/commands/concerns"
|
|
4
|
+
require_relative "commands/book"
|
|
5
|
+
|
|
6
|
+
module BridgetownWritebook
|
|
7
|
+
class Commands
|
|
8
|
+
include Bridgetown::Commands::ConfigurationOverridable
|
|
9
|
+
|
|
10
|
+
Bridgetown::Commands::Registrations.register do
|
|
11
|
+
desc "book <command>", "Take me to the book"
|
|
12
|
+
subcommand "book", Book
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgetownWritebook
|
|
4
|
+
module Models
|
|
5
|
+
class Book
|
|
6
|
+
attr_accessor :name, :subtitle, :resource, :meta, :chapters
|
|
7
|
+
|
|
8
|
+
delegate :id, to: :resource
|
|
9
|
+
alias_method :title, :name
|
|
10
|
+
|
|
11
|
+
def initialize(book, chapters:, meta:)
|
|
12
|
+
@resource = book
|
|
13
|
+
@meta = meta
|
|
14
|
+
@chapters = []
|
|
15
|
+
|
|
16
|
+
chapters.each do |chapter|
|
|
17
|
+
@chapters << Chapter.new(chapter, booxk: self)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
extract_metadata
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#TODO: support other formats as well.
|
|
24
|
+
def cover
|
|
25
|
+
"/#{resource.path.split(".").first}/cover.png"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def authors?
|
|
29
|
+
@authors.present?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def authors
|
|
33
|
+
"by #{@authors.join(", ")}" if authors?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def extract_metadata
|
|
37
|
+
@name = @meta&.data&.title || slug.titleize
|
|
38
|
+
@subtitle = @meta&.data&.subtitle
|
|
39
|
+
@authors = @meta&.data&.authors
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def slug
|
|
43
|
+
id.split("/").last.split(".md").first
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def link
|
|
47
|
+
resource.relative_url
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def chapter_ids
|
|
51
|
+
chapters.map(&:id)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def generate
|
|
55
|
+
resource.data.layout = :book
|
|
56
|
+
resource.data.title = title
|
|
57
|
+
resource.data.cover = cover
|
|
58
|
+
resource.data.subtitle = subtitle
|
|
59
|
+
resource.data.authors = authors
|
|
60
|
+
resource.content = content
|
|
61
|
+
|
|
62
|
+
chapters.each(&:generate)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def content
|
|
66
|
+
<<~HTML
|
|
67
|
+
<ul class="pl-0" data-controller="bookmark" data-bookmark-chapter-outlet='.chapter' data-bookmark-book-value="#{text id}">
|
|
68
|
+
#{html chapters.map do |chapter|
|
|
69
|
+
li chapter
|
|
70
|
+
end.join }
|
|
71
|
+
</ul>
|
|
72
|
+
HTML
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# TODO: may be convert these into compenents or partials.
|
|
76
|
+
# TODO: Move them to the template, add it to the metadata and move it to the template.
|
|
77
|
+
def li(chapter)
|
|
78
|
+
<<~HTML
|
|
79
|
+
<li class='chapter flex justify-between items-end gap-4'
|
|
80
|
+
data-controller='chapter'
|
|
81
|
+
data-chapter-id-value='#{text chapter.id}'
|
|
82
|
+
data-chapter-ellipsis-class="text-orange-500"
|
|
83
|
+
>
|
|
84
|
+
<a href='#{text chapter.link}' class="text-nowrap">#{text chapter.title}</a>
|
|
85
|
+
<span class="grow overflow-hidden border-b border-dotted border-black mb-1.5" data-chapter-target="ellipsis"></span>
|
|
86
|
+
<span class="text-nowrap">#{text chapter.word_count}</span>
|
|
87
|
+
</li>
|
|
88
|
+
HTML
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgetownWritebook
|
|
4
|
+
module Models
|
|
5
|
+
class Chapter
|
|
6
|
+
attr_accessor :name, :slug, :resource, :book
|
|
7
|
+
|
|
8
|
+
delegate :id, :data, to: :resource
|
|
9
|
+
|
|
10
|
+
def initialize(chapter, book:)
|
|
11
|
+
@resource = chapter
|
|
12
|
+
@book = book
|
|
13
|
+
|
|
14
|
+
# Populate the word count before adding the stimulus controller
|
|
15
|
+
calculate_word_count
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def calculate_word_count
|
|
19
|
+
words_array = resource.content.split - %w[#]
|
|
20
|
+
@word_count = words_array.size
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def delimited_word_count
|
|
24
|
+
@word_count.to_fs(:delimited)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def word_count
|
|
28
|
+
return "#{delimited_word_count} words" if @word_count > 1
|
|
29
|
+
|
|
30
|
+
"#{delimited_word_count} word"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def link
|
|
34
|
+
resource.relative_url
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def title
|
|
38
|
+
data.title
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def next_chapter
|
|
42
|
+
book.chapters[book.chapters.index(self) + 1]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def generate
|
|
46
|
+
resource.data.layout = "chapter"
|
|
47
|
+
resource.data.book_title = book.name
|
|
48
|
+
resource.data.book_link = book.link
|
|
49
|
+
resource.data.next_chapter_title = next_chapter&.title
|
|
50
|
+
resource.data.next_chapter_link = next_chapter&.link
|
|
51
|
+
resource.data.word_count = word_count
|
|
52
|
+
resource.content = <<~HTML
|
|
53
|
+
#{html resource.content}
|
|
54
|
+
<div data-controller="reading"
|
|
55
|
+
data-reading-id-value="#{text id}"
|
|
56
|
+
data-reading-book-value="#{text book.id}">
|
|
57
|
+
</div>
|
|
58
|
+
HTML
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'active_support/core_ext/numeric/conversions'
|
|
2
|
+
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
class Builders::Books < SiteBuilder
|
|
5
|
+
def initialize(name = nil, current_site = nil)
|
|
6
|
+
super
|
|
7
|
+
@books = []
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def build
|
|
11
|
+
generator do
|
|
12
|
+
create_book_objects
|
|
13
|
+
generate_books
|
|
14
|
+
generate_index_page_for_books
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def generate_index_page_for_books
|
|
19
|
+
books = @books
|
|
20
|
+
book_covers = books.map { |book| cover_for(book) }.join
|
|
21
|
+
add_resource nil, "books.md" do
|
|
22
|
+
layout "default"
|
|
23
|
+
permalink "/books/"
|
|
24
|
+
content <<-HTML
|
|
25
|
+
<ul class="list-none flex justify-center sm:grid sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-y-6 py-10 px-0 flex-wrap">
|
|
26
|
+
#{book_covers}
|
|
27
|
+
</ul>
|
|
28
|
+
HTML
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def cover_for(book)
|
|
33
|
+
chapters_json = book.chapter_ids.to_json.gsub('"', '"')
|
|
34
|
+
|
|
35
|
+
<<-HTML
|
|
36
|
+
<li data-controller="book" data-book-id-value="#{book.id}" data-book-chapters-value="#{chapters_json}" >
|
|
37
|
+
<a class="flex flex-col gap-2 max-w-[236px]" href="#{book.link}">
|
|
38
|
+
<div class="max-h-[378px] border rounded relative box-border" data-book-target="cover">
|
|
39
|
+
<img src="#{book.cover}" class="max-h-[378px] max-w-[236px] rounded">
|
|
40
|
+
</div>
|
|
41
|
+
<div class="text-center">#{book.name}</div>
|
|
42
|
+
<div class="text-sm text-center">#{book.authors}</div>
|
|
43
|
+
</a>
|
|
44
|
+
</li>
|
|
45
|
+
HTML
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create_book_objects
|
|
49
|
+
site.collections.books.resources
|
|
50
|
+
.group_by { |b| b.id.split("_books/").last.split("/").first }
|
|
51
|
+
.each do |book_id, chapters|
|
|
52
|
+
meta_file = chapters.find { |c| c.relative_path.to_s.end_with?('00-meta.md') }
|
|
53
|
+
regular_chapters = chapters.reject { |c| c.relative_path.to_s.end_with?('00-meta.md') }
|
|
54
|
+
|
|
55
|
+
resource = add_resource(:book, "books/#{book_id}.md") { permalink "/books/:slug/" }
|
|
56
|
+
@books << Book.new(resource, chapters: regular_chapters, meta: meta_file)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def generate_books
|
|
61
|
+
@books.each(&:generate)
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/bridgetown_writebook.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bridgetown_writebook
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.0
|
|
4
|
+
version: 0.1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bridgetown Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-08-
|
|
11
|
+
date: 2025-08-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bridgetown
|
|
@@ -80,6 +80,10 @@ extra_rdoc_files: []
|
|
|
80
80
|
files:
|
|
81
81
|
- ".github/workflows/tests.yml"
|
|
82
82
|
- ".gitignore"
|
|
83
|
+
- ".idea/.gitignore"
|
|
84
|
+
- ".idea/bridgetown_writebook.iml"
|
|
85
|
+
- ".idea/modules.xml"
|
|
86
|
+
- ".idea/vcs.xml"
|
|
83
87
|
- ".rubocop.yml"
|
|
84
88
|
- CHANGELOG.md
|
|
85
89
|
- Gemfile
|
|
@@ -95,6 +99,12 @@ files:
|
|
|
95
99
|
- layouts/bridgetown_writebook/layout.html
|
|
96
100
|
- lib/bridgetown_writebook.rb
|
|
97
101
|
- lib/bridgetown_writebook/builder.rb
|
|
102
|
+
- lib/bridgetown_writebook/commands.rb
|
|
103
|
+
- lib/bridgetown_writebook/commands/book.rb
|
|
104
|
+
- lib/bridgetown_writebook/commands/chapter.rb
|
|
105
|
+
- lib/bridgetown_writebook/models/book.rb
|
|
106
|
+
- lib/bridgetown_writebook/models/chapter.rb
|
|
107
|
+
- lib/bridgetown_writebook/models/something.rb
|
|
98
108
|
- lib/bridgetown_writebook/version.rb
|
|
99
109
|
- package.json
|
|
100
110
|
homepage: https://github.com/username/bridgetown_writebook
|