class Qti::Models::Base

Attributes

doc[R]
manifest[RW]
package_root[R]
path[R]
resource[R]

Public Class Methods

from_path!(path, package_root = nil, resource = nil) click to toggle source
# File lib/qti/models/base.rb, line 16
def self.from_path!(path, package_root = nil, resource = nil)
  new(path: path, package_root: package_root, resource: resource)
end
new(path:, package_root: nil, html: false, resource: nil) click to toggle source
# File lib/qti/models/base.rb, line 20
def initialize(path:, package_root: nil, html: false, resource: nil)
  @path = path
  @resource = resource
  self.package_root = package_root || File.dirname(path)
  @doc = html ? parse_html(File.read(path)) : parse_xml(File.read(path))
  raise ArgumentError unless @doc
  preprocess_xml_doc(@doc) unless html
end

Public Instance Methods

css_with_single_check(css) click to toggle source
# File lib/qti/models/base.rb, line 49
def css_with_single_check(css)
  node_list = @doc.css(css)
  raise Qti::ParseError, 'Too many matches' if node_list.count > 1
  node_list.first
end
parse_html(html_string) click to toggle source
# File lib/qti/models/base.rb, line 59
def parse_html(html_string)
  Nokogiri.HTML(html_string, @path.to_s, &:noblanks)
end
parse_xml(xml_string) click to toggle source
# File lib/qti/models/base.rb, line 55
def parse_xml(xml_string)
  Nokogiri.XML(xml_string, @path.to_s, &:noblanks)
end
preprocess_xml_doc(xml_doc) click to toggle source
# File lib/qti/models/base.rb, line 29
def preprocess_xml_doc(xml_doc)
  converter = Mathml2latex::Converter.new
  converter.replace_with_latex(xml_doc)
  nodes = xml_doc.xpath('//mm:latex', 'mm' => Mathml2latex::INSTUCTURE_LATEX_NS)

  nodes.each do |node|
    # convert all #160 space to regular #32 whitespace
    # latex parser won't work for #160 space
    text = node.text.tr("\u00a0", ' ')
    latex_string = " \\(#{text}\\) "
    node.replace(latex_string)
  end
end
raise_unsupported(message = 'Unsupported QTI version') click to toggle source
# File lib/qti/models/base.rb, line 76
def raise_unsupported(message = 'Unsupported QTI version')
  raise Qti::UnsupportedSchema, message
end
remap_href_path(href) click to toggle source
# File lib/qti/models/base.rb, line 63
def remap_href_path(href)
  return nil unless href
  path = File.join(File.dirname(@path), href)
  if @package_root.nil?
    raise Qti::ParseError, "Potentially unsafe href '#{href}'" if href.split('/').include?('..')
  else
    unless Pathname.new(path).cleanpath.to_s.start_with?(@package_root)
      raise Qti::ParseError, "Unsafe href '#{href}'"
    end
  end
  path
end
sanitize_content!(html) click to toggle source
# File lib/qti/models/base.rb, line 12
def sanitize_content!(html)
  sanitizer.clean(html)
end
xpath_with_single_check(xpath) click to toggle source
# File lib/qti/models/base.rb, line 43
def xpath_with_single_check(xpath)
  node_list = @doc.xpath(xpath)
  raise Qti::ParseError, 'Too many matches' if node_list.count > 1
  node_list.first
end

Protected Instance Methods

copy_paths_from_item(other_item) click to toggle source
# File lib/qti/models/base.rb, line 93
def copy_paths_from_item(other_item)
  @package_root = other_item.package_root
  @path = other_item.path
end
package_root=(package_root) click to toggle source
# File lib/qti/models/base.rb, line 82
def package_root=(package_root)
  @package_root = package_root
  return unless @package_root
  @package_root = Pathname.new(@package_root).cleanpath.to_s + '/'
end
relative_path() click to toggle source
# File lib/qti/models/base.rb, line 88
def relative_path
  return nil if @path.nil? || @package_root.nil?
  @path.sub(/\A#{Regexp.quote(@package_root)}/, '')
end

Private Instance Methods

sanitizer() click to toggle source
# File lib/qti/models/base.rb, line 100
def sanitizer
  @sanitizer ||= Sanitizer.new
end