Class: Softcover::BookManifest
- Inherits:
-
OpenStruct
- Object
- OpenStruct
- Softcover::BookManifest
- Includes:
- Utils
- Defined in:
- lib/softcover/book_manifest.rb
Defined Under Namespace
Classes: Chapter, NotFound, Section
Constant Summary collapse
- MD_PATH =
'Book.txt'- YAML_PATH =
"book.yml"
Constants included from Utils
Class Method Summary collapse
-
.find_book_root! ⇒ Object
Changes the directory until in the book’s root directory.
- .not_found! ⇒ Object
- .valid_directory? ⇒ Boolean
Instance Method Summary collapse
-
#chapter_file_paths ⇒ Object
Returns an iterator for the chapter file paths.
-
#chapter_includes(string) ⇒ Object
Returns an array of the chapters to include.
- #find_chapter_by_number(number) ⇒ Object
- #find_chapter_by_slug(slug) ⇒ Object
-
#first_chapter ⇒ Object
Returns the first full chapter.
-
#frontmatter? ⇒ Boolean
Returns true if the book has frontmatter.
-
#initialize(options = {}) ⇒ BookManifest
constructor
A new instance of BookManifest.
-
#markdown? ⇒ Boolean
(also: #md?)
Returns true if converting Markdown source.
-
#pdf_chapter_filenames ⇒ Object
Returns the full chapter filenames for the PDF.
-
#pdf_chapter_names ⇒ Object
Returns chapters for the PDF.
-
#polytex? ⇒ Boolean
Returns true if converting PolyTeX source.
-
#polytex_dir ⇒ Object
Returns the directory where the LaTeX files are located.
-
#preview_chapter_range ⇒ Object
Returns the chapter range for book previews.
-
#preview_chapters ⇒ Object
Returns the chapters to use in the preview as a range.
-
#remove_frontmatter(base_contents, frontmatter) ⇒ Object
Removes frontmatter.
-
#url(chapter_number) ⇒ Object
Returns a URL for the chapter with the given number.
Methods included from Utils
#add_highlight_class!, #as_size, #current_book, #digest, #executable, #execute, #in_book_directory?, #logged_in?, #mkdir, #path, #reset_current_book!, #rm, #silence, #source, #tmpify, #write_pygments_file
Constructor Details
#initialize(options = {}) ⇒ BookManifest
Returns a new instance of BookManifest.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/softcover/book_manifest.rb', line 47 def initialize( = {}) @source = [:source] || :polytex @origin = [:origin] yaml_attrs = read_from_yml attrs = case when polytex? then yaml_attrs when markdown? then yaml_attrs.merge(read_from_md) else self.class.not_found! end.symbolize_keys! marshal_load attrs if polytex? tex_filename = filename + '.tex' self.chapters = [] self.frontmatter = [] base_contents = File.read(tex_filename) if base_contents.match(/frontmatter/) @frontmatter = true chapters.push Chapter.new(slug: 'frontmatter', title: 'Frontmatter', sections: nil, chapter_number: 0) end raw_frontmatter = remove_frontmatter(base_contents, frontmatter) if frontmatter? self.frontmatter = chapter_includes(raw_frontmatter) else self.frontmatter = [] end self. = base_contents.scan(/^\s*\\author\{(.*?)\}/).flatten.first chapter_includes(base_contents).each_with_index do |name, i| slug = File.basename(name, '.*') title_regex = /^\s*\\chapter{(.*)}/ content = File.read(File.join(polytex_dir, slug + '.tex')) title = content[title_regex, 1] j = 0 sections = content.scan(/^\s*\\section{(.*)}/).flatten.map do |name| Section.new(name: name, section_number: j += 1) end chapters.push Chapter.new(slug: slug, title: title, sections: sections, chapter_number: i + 1) end end verify_paths! if [:verify_paths] end |
Class Method Details
.find_book_root! ⇒ Object
Changes the directory until in the book’s root directory.
218 219 220 221 222 223 224 |
# File 'lib/softcover/book_manifest.rb', line 218 def self.find_book_root! loop do return true if valid_directory? return not_found! if Dir.pwd == '/' Dir.chdir '..' end end |
.not_found! ⇒ Object
226 227 228 |
# File 'lib/softcover/book_manifest.rb', line 226 def self.not_found! raise NotFound end |
.valid_directory? ⇒ Boolean
213 214 215 |
# File 'lib/softcover/book_manifest.rb', line 213 def self.valid_directory? [YAML_PATH, MD_PATH].any? { |f| File.exist?(f) } end |
Instance Method Details
#chapter_file_paths ⇒ Object
Returns an iterator for the chapter file paths.
153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/softcover/book_manifest.rb', line 153 def chapter_file_paths pdf_chapter_names.map do |name| file_path = case when markdown? || @origin == :markdown File.join("chapters", "#{name}.md") when polytex? File.join("chapters", "#{name}.tex") end yield file_path if block_given? file_path end end |
#chapter_includes(string) ⇒ Object
Returns an array of the chapters to include.
108 109 110 111 |
# File 'lib/softcover/book_manifest.rb', line 108 def chapter_includes(string) chapter_regex = /^\s*\\include\{#{polytex_dir}\/(.*?)\}/ string.scan(chapter_regex).flatten end |
#find_chapter_by_number(number) ⇒ Object
186 187 188 |
# File 'lib/softcover/book_manifest.rb', line 186 def find_chapter_by_number(number) chapters.find { |chapter| chapter.chapter_number == number } end |
#find_chapter_by_slug(slug) ⇒ Object
182 183 184 |
# File 'lib/softcover/book_manifest.rb', line 182 def find_chapter_by_slug(slug) chapters.find { |chapter| chapter.slug == slug } end |
#first_chapter ⇒ Object
Returns the first full chapter. This arranges to skip the frontmatter, if any.
137 138 139 |
# File 'lib/softcover/book_manifest.rb', line 137 def first_chapter frontmatter? ? chapters[1] : chapters[0] end |
#frontmatter? ⇒ Boolean
Returns true if the book has frontmatter.
131 132 133 |
# File 'lib/softcover/book_manifest.rb', line 131 def frontmatter? @frontmatter end |
#markdown? ⇒ Boolean Also known as: md?
Returns true if converting Markdown source.
142 143 144 |
# File 'lib/softcover/book_manifest.rb', line 142 def markdown? @source == :markdown || @source == :md end |
#pdf_chapter_filenames ⇒ Object
Returns the full chapter filenames for the PDF.
178 179 180 |
# File 'lib/softcover/book_manifest.rb', line 178 def pdf_chapter_filenames pdf_chapter_names.map { |name| File.join(polytex_dir, "#{name}.tex") } end |
#pdf_chapter_names ⇒ Object
Returns chapters for the PDF. The frontmatter pseudo-chapter exists for the sake of HTML/EPUB/MOBI, so it’s not returned as part of the chapters.
171 172 173 174 175 |
# File 'lib/softcover/book_manifest.rb', line 171 def pdf_chapter_names chaps = chapters.reject { |chapter| chapter.slug.match(/frontmatter/) }. collect(&:slug) frontmatter? ? frontmatter + chaps : chaps end |
#polytex? ⇒ Boolean
Returns true if converting PolyTeX source.
148 149 150 |
# File 'lib/softcover/book_manifest.rb', line 148 def polytex? @source == :polytex end |
#polytex_dir ⇒ Object
Returns the directory where the LaTeX files are located. We put them in the a separate directory when using them as an intermediate format when working with Markdown books. Otherwise, we use the chapters directory, which is the default location when writing LaTeX/PolyTeX books.
101 102 103 104 105 |
# File 'lib/softcover/book_manifest.rb', line 101 def polytex_dir dir = (markdown? || @origin == :markdown) ? 'generated_polytex' : 'chapters' mkdir dir dir end |
#preview_chapter_range ⇒ Object
Returns the chapter range for book previews. We could ‘eval` the range, but that would allow users to execute arbitrary code (maybe not a big problem on their system, but it would be a Bad Thing on a server).
203 204 205 206 |
# File 'lib/softcover/book_manifest.rb', line 203 def preview_chapter_range first, last = epub_mobi_preview_chapter_range.split('..').map(&:to_i) first..last end |
#preview_chapters ⇒ Object
Returns the chapters to use in the preview as a range.
209 210 211 |
# File 'lib/softcover/book_manifest.rb', line 209 def preview_chapters chapters[preview_chapter_range] end |
#remove_frontmatter(base_contents, frontmatter) ⇒ Object
Removes frontmatter. The frontmatter shouldn’t be included in the chapter slugs, so we remove it. For example, in
\frontmatter
\maketitle
\tableofcontents
% List frontmatter sections here (preface, foreword, etc.).
\include{chapters/preface}
\mainmatter
% List chapters here in the order they should appear in the book.
\include{chapters/a_chapter}
we don’t want to include the preface.
125 126 127 128 |
# File 'lib/softcover/book_manifest.rb', line 125 def remove_frontmatter(base_contents, frontmatter) base_contents.gsub!(/\\frontmatter(.*)\\mainmatter/m, '') $1 end |
#url(chapter_number) ⇒ Object
Returns a URL for the chapter with the given number.
191 192 193 194 195 196 197 |
# File 'lib/softcover/book_manifest.rb', line 191 def url(chapter_number) if (chapter = find_chapter_by_number(chapter_number)) chapter.slug else '#' end end |