Class: OpenStax::Content::Page

Inherits:
Object
  • Object
show all
Defined in:
lib/openstax/content/page.rb

Constant Summary collapse

ROOT_CSS =

Start parsing here

'html > body'
SNAP_LAB_CSS =

Find snap lab notes

'.snap-lab'
SNAP_LAB_TITLE_CSS =
'[data-type="title"]'
LO_DEF_NODE_CSS =

Find nodes that define relevant tags

'.ost-learning-objective-def'
STD_DEF_NODE_CSS =
'.ost-standards-def'
TEKS_DEF_NODE_CSS =
'.ost-standards-teks'
APBIO_DEF_NODE_CSS =
'.ost-standards-apbio'
STD_NAME_NODE_CSS =
'.ost-standards-name'
STD_DESC_NODE_CSS =
'.ost-standards-description'
LO_REGEX =

Find specific tags and extract the relevant parts

/ost-tag-lo-([\w+-]+)/
STD_REGEX =
/ost-tag-std-([\w+-]+)/
TEKS_REGEX =
/ost-tag-(teks-[\w+-]+)/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(book: nil, hash: {}, uuid: nil, url: nil, title: nil, content: nil) ⇒ Page

Returns a new instance of Page.

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
# File 'lib/openstax/content/page.rb', line 35

def initialize(book: nil, hash: {}, uuid: nil, url: nil, title: nil, content: nil)
  @uuid    = uuid || hash['id']&.split('@', 2)&.first
  raise ArgumentError, 'Either uuid or hash with id key is required' if @uuid.nil?

  @book    = book
  @hash    = hash
  @url     = url
  @title   = title || hash['title']
  @content = content
end

Instance Attribute Details

#chapter_sectionObject

Returns the value of attribute chapter_section.



46
47
48
# File 'lib/openstax/content/page.rb', line 46

def chapter_section
  @chapter_section
end

#hashObject (readonly)

Returns the value of attribute hash.



47
48
49
# File 'lib/openstax/content/page.rb', line 47

def hash
  @hash
end

#uuidObject (readonly)

Returns the value of attribute uuid.



47
48
49
# File 'lib/openstax/content/page.rb', line 47

def uuid
  @uuid
end

Class Method Details

.feature_node(node, feature_ids) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/openstax/content/page.rb', line 27

def self.feature_node(node, feature_ids)
  feature_ids = [feature_ids].flatten
  return if feature_ids.empty?

  feature_id_css = feature_ids.map { |feature_id| "##{feature_id}" }.join(', ')
  node.at_css(feature_id_css)
end

Instance Method Details

#aplosObject



117
118
119
# File 'lib/openstax/content/page.rb', line 117

def aplos
  @aplos ||= tags.select { |tag| tag[:type] == :aplo }.map { |tag| tag[:value] }
end

#bookObject

Raises:

  • (ArgumentError)


49
50
51
52
53
# File 'lib/openstax/content/page.rb', line 49

def book
  raise ArgumentError, 'Book was not specified' if @book.nil?

  @book
end

#book_locationObject



63
64
65
# File 'lib/openstax/content/page.rb', line 63

def book_location
  parsed_title.book_location
end

#contentObject



79
80
81
# File 'lib/openstax/content/page.rb', line 79

def content
  @content ||= full_hash.fetch('content')
end

#convert_content!Object

Replaces links to embeddable sims (and maybe videos in the future) with iframes Changes exercise urls in the doc to be absolute



97
98
99
100
101
102
103
# File 'lib/openstax/content/page.rb', line 97

def convert_content!
  OpenStax::Content::Fragment::Interactive.replace_interactive_links_with_iframes!(doc)
  OpenStax::Content::Fragment::Exercise.absolutize_exercise_urls!(doc)
  map_note_format!(doc)
  @content = doc.to_html
  @root = nil
end

#docObject



83
84
85
# File 'lib/openstax/content/page.rb', line 83

def doc
  @doc ||= Nokogiri::HTML(content)
end

#footnotesObject



91
92
93
# File 'lib/openstax/content/page.rb', line 91

def footnotes
  @footnotes ||= doc.css('[role=doc-footnote]')
end

#full_hashObject



71
72
73
# File 'lib/openstax/content/page.rb', line 71

def full_hash
  @full_hash ||= book.archive.json url
end

#losObject



113
114
115
# File 'lib/openstax/content/page.rb', line 113

def los
  @los ||= tags.select { |tag| tag[:type] == :lo }.map { |tag| tag[:value] }
end

#parsed_titleObject



59
60
61
# File 'lib/openstax/content/page.rb', line 59

def parsed_title
  @parsed_title ||= OpenStax::Content::Title.new @title
end

#rootObject



87
88
89
# File 'lib/openstax/content/page.rb', line 87

def root
  @root ||= doc.at_css(ROOT_CSS)
end

#short_idObject



75
76
77
# File 'lib/openstax/content/page.rb', line 75

def short_id
  @short_id ||= full_hash.fetch('shortId', nil)
end

#snap_lab_nodesObject



105
106
107
# File 'lib/openstax/content/page.rb', line 105

def snap_lab_nodes
  root.css(SNAP_LAB_CSS)
end

#snap_lab_title(snap_lab) ⇒ Object



109
110
111
# File 'lib/openstax/content/page.rb', line 109

def snap_lab_title(snap_lab)
  snap_lab.at_css(SNAP_LAB_TITLE_CSS).try(:text)
end

#tagsObject



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/openstax/content/page.rb', line 121

def tags
  return @tags.values unless @tags.nil?

  # Start with default cnxmod tag
  cnxmod_value = "context-cnxmod:#{uuid}"
  @tags = { cnxmod_value => { value: cnxmod_value, type: :cnxmod } }

  # Extract tag name and description from .ost-standards-def and .os-learning-objective-def.

  # LO tags
  root.css(LO_DEF_NODE_CSS).each do |node|
    klass = node.attr('class')
    lo_value = LO_REGEX.match(klass).try(:[], 1)
    next if lo_value.nil?

    teks_value = TEKS_REGEX.match(klass).try(:[], 1)
    description = node.content.strip

    @tags[lo_value] = {
      value: lo_value,
      description: description,
      teks: teks_value,
      type: :lo
    }
  end

  # Other standards
  root.css(STD_DEF_NODE_CSS).each do |node|
    klass = node.attr('class')
    name = node.at_css(STD_NAME_NODE_CSS).try(:content).try(:strip)
    description = node.at_css(STD_DESC_NODE_CSS).try(:content).try(:strip)
    value = nil

    if node.matches?(TEKS_DEF_NODE_CSS)
      value = TEKS_REGEX.match(klass).try(:[], 1)
      type = :teks
    elsif node.matches?(APBIO_DEF_NODE_CSS)
      value = LO_REGEX.match(klass).try(:[], 1)
      type = :aplo
    end

    next if value.nil?

    @tags[value] = {
      value: value,
      name: name,
      description: description,
      type: type
    }
  end

  @tags.values
end

#titleObject



67
68
69
# File 'lib/openstax/content/page.rb', line 67

def title
  parsed_title.text
end

#urlObject



55
56
57
# File 'lib/openstax/content/page.rb', line 55

def url
  @url ||= "#{book.url_fragment}:#{uuid}.json"
end