Class: WritersRoom::Element

Inherits:
Object
  • Object
show all
Defined in:
lib/writers_room/element.rb

Overview

Lightweight value object wrapping a FrontMatter file. Represents any story element: character, location, chapter, theme, etc.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path:, metadata: {}, body: "") ⇒ Element

Returns a new instance of Element.



11
12
13
14
15
16
# File 'lib/writers_room/element.rb', line 11

def initialize(path:, metadata: {}, body: "")
  @path     = path
  @slug     = File.basename(path, ".md")
  @metadata = 
  @body     = body
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



9
10
11
# File 'lib/writers_room/element.rb', line 9

def body
  @body
end

#metadataObject (readonly)

Returns the value of attribute metadata.



9
10
11
# File 'lib/writers_room/element.rb', line 9

def 
  @metadata
end

#pathObject (readonly)

Returns the value of attribute path.



9
10
11
# File 'lib/writers_room/element.rb', line 9

def path
  @path
end

#slugObject (readonly)

Returns the value of attribute slug.



9
10
11
# File 'lib/writers_room/element.rb', line 9

def slug
  @slug
end

Class Method Details

.create(dir, name, metadata: {}, body: "") ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/writers_room/element.rb', line 54

def self.create(dir, name, metadata: {}, body: "")
  slug = sanitize(name)
  path = File.join(dir, "#{slug}.md")

  raise Error, "'#{name}' already exists at #{path}" if File.exist?(path)

  FileUtils.mkdir_p(dir)
  meta = { "name" => name }.merge(FrontMatter.stringify_keys())
  content = FrontMatter.dump(meta, body)
  File.write(path, content)

  load(path)
end

.load(path, symbolize_keys: true) ⇒ Object



49
50
51
52
# File 'lib/writers_room/element.rb', line 49

def self.load(path, symbolize_keys: true)
  parsed = FrontMatter.load_file(path, symbolize_keys: symbolize_keys)
  new(path: path, metadata: parsed[:metadata], body: parsed[:body])
end

.sanitize(name) ⇒ Object



87
88
89
# File 'lib/writers_room/element.rb', line 87

def self.sanitize(name)
  name.to_s.downcase.gsub(/[^a-z0-9]+/, "_").gsub(/(^_|_$)/, "")
end

Instance Method Details

#aliasesObject



22
23
24
# File 'lib/writers_room/element.rb', line 22

def aliases
  Array([:aliases] || ["aliases"])
end

#based_onObject



38
39
40
# File 'lib/writers_room/element.rb', line 38

def based_on
  [:based_on] || ["based_on"]
end

#element_typeObject



26
27
28
# File 'lib/writers_room/element.rb', line 26

def element_type
  [:element_type] || ["element_type"]
end

#matches_name?(query) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
45
46
47
# File 'lib/writers_room/element.rb', line 42

def matches_name?(query)
  normalized = query.to_s.downcase.strip
  return true if slug == sanitize(normalized)
  return true if name.downcase == normalized
  aliases.any? { |a| a.to_s.downcase == normalized }
end

#nameObject



18
19
20
# File 'lib/writers_room/element.rb', line 18

def name
  [:name] || ["name"] || slug.tr("_", " ").split.map(&:capitalize).join(" ")
end

#reloadObject



75
76
77
78
79
80
# File 'lib/writers_room/element.rb', line 75

def reload
  parsed = FrontMatter.load_file(@path, symbolize_keys: true)
  @metadata = parsed[:metadata]
  @body     = parsed[:body]
  self
end

#saveObject



68
69
70
71
72
73
# File 'lib/writers_room/element.rb', line 68

def save
  meta = FrontMatter.stringify_keys(@metadata)
  content = FrontMatter.dump(meta, @body)
  File.write(@path, content)
  self
end

#statusObject



34
35
36
# File 'lib/writers_room/element.rb', line 34

def status
  [:status] || ["status"]
end

#to_hObject



82
83
84
85
# File 'lib/writers_room/element.rb', line 82

def to_h
  { slug: slug, name: name, aliases: aliases, path: path,
    version: version, status: status }
end

#versionObject



30
31
32
# File 'lib/writers_room/element.rb', line 30

def version
  [:version] || ["version"]
end