bridgetown_writebook 0.1.0 → 0.1.0.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/bridgetown.automation.rb +1 -1
- 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/version.rb +1 -1
- data/lib/bridgetown_writebook.rb +1 -0
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ecde4cf7c2246af31a117f402935e342064314ab25f9ce3c38c50520682a769
|
|
4
|
+
data.tar.gz: 78fcd4f3b88571eb92f8953c627b01bb19a17145d0b94251955dfd46462213c2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dcd86b0250d74ca12824716bac756083d46e1990b4fd86e698c35928a1250f32d955048d07bf074b2dac8176a7f91621e3797f5b60a66e86c49d7535fa9f1f58
|
|
7
|
+
data.tar.gz: 391edeb2c0e1dc1b5502da043b23df3ea71f7db0570b3b1dddeb71cb71041b37d2493a6324768a7200a06e5556805fcdec0e48d569816c878e8e761c6461b4e4
|
data/bridgetown.automation.rb
CHANGED
|
@@ -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 "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
|
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.1
|
|
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
|
|
@@ -95,6 +95,11 @@ files:
|
|
|
95
95
|
- layouts/bridgetown_writebook/layout.html
|
|
96
96
|
- lib/bridgetown_writebook.rb
|
|
97
97
|
- lib/bridgetown_writebook/builder.rb
|
|
98
|
+
- lib/bridgetown_writebook/commands.rb
|
|
99
|
+
- lib/bridgetown_writebook/commands/book.rb
|
|
100
|
+
- lib/bridgetown_writebook/commands/chapter.rb
|
|
101
|
+
- lib/bridgetown_writebook/models/book.rb
|
|
102
|
+
- lib/bridgetown_writebook/models/chapter.rb
|
|
98
103
|
- lib/bridgetown_writebook/version.rb
|
|
99
104
|
- package.json
|
|
100
105
|
homepage: https://github.com/username/bridgetown_writebook
|