<commit_before>require "taxpub/exceptions"
require "taxpub/validator"
require "taxpub/version"
require "nokogiri"
require "open-uri"
require "set"

class Taxpub

  def initialize
    @parameters = {}
    @doc = {}
  end

  ##
  # View the built parameters
  #
  def params
    @parameters
  end

  ##
  # Specify a remote TaxPub URL
  # Source must be an xml file
  #
  # == Example
  #
  #   instance.url = "https://tdwgproceedings.pensoft.net/article/15141/download/xml/"
  #
  def url=(url)
    Validator.validate_url(url)
    @parameters[:url] = url
  end

  def url
    @parameters[:url] || nil
  end

  ##
  # Set a file path for a TaxPub XML file
  #
  # == Example
  #
  #   instance.file_path = "/Users/jane/Desktop/taxpub.xml"
  #
  def file_path=(file_path)
    Validator.validate_type(file_path, 'File')
    @parameters[:file] = File.new(file_path, "r")
  end

  def file_path
    @parameters[:file].path rescue nil
  end

  def parse
    if url
      @doc = Nokogiri::XML(open(url))
    elsif file_path
      @doc = File.open(file_path) { |f| Nokogiri::XML(f) }
    end
    Validator.validate_nokogiri(@doc)
  end

  def doc
    @doc
  end

  def doi
    Validator.validate_nokogiri(@doc)
    expand_doi(@doc.xpath("//*/article-meta/article-id[@pub-id-type='doi']").text)
  end

  def title
    Validator.validate_nokogiri(@doc)
    t = @doc.xpath("//*/article-meta/title-group/article-title").text
    clean_text(t)
  end

  def abstract
    Validator.validate_nokogiri(@doc)
    a = @doc.xpath("//*/article-meta/abstract/*/p").text
    clean_text(a)
  end

  def keywords
    Validator.validate_nokogiri(@doc)
    @doc.xpath("//*/article-meta/kwd-group/kwd").map(&:text) rescue []
  end

  def authors
    Validator.validate_nokogiri(@doc)
    data = []
    @doc.xpath("//*/contrib[@contrib-type='author']").each do |author|
      rid = author.xpath("xref").attr("rid").value
      affiliation = clean_text(@doc.xpath("//*/aff[@id='#{rid}']/addr-line").text)
      orcid = author.xpath("uri[@content-type='orcid']").text rescue nil
      given = clean_text(author.xpath("name/given-names").text)
      surname = clean_text(author.xpath("name/surname").text)
      data << { 
        given: given,
        surname: surname,
        fullname: [given, surname].join(" "),
        email: author.xpath("email").text,
        affiliation: affiliation,
        orcid: orcid
      }
    end
    data
  end

  def conference_part
    Validator.validate_nokogiri(@doc)
    coll = @doc.xpath("//*/subj-group[@subj-group-type='conference-part']/subject").text
    clean_text(coll)
  end<commit_msg>Fix for when affiliation not present<commit_after>require "taxpub/exceptions"
require "taxpub/validator"
require "taxpub/version"
require "nokogiri"
require "open-uri"
require "set"

class Taxpub

  def initialize
    @parameters = {}
    @doc = {}
  end

  ##
  # View the built parameters
  #
  def params
    @parameters
  end

  ##
  # Specify a remote TaxPub URL
  # Source must be an xml file
  #
  # == Example
  #
  #   instance.url = "https://tdwgproceedings.pensoft.net/article/15141/download/xml/"
  #
  def url=(url)
    Validator.validate_url(url)
    @parameters[:url] = url
  end

  def url
    @parameters[:url] || nil
  end

  ##
  # Set a file path for a TaxPub XML file
  #
  # == Example
  #
  #   instance.file_path = "/Users/jane/Desktop/taxpub.xml"
  #
  def file_path=(file_path)
    Validator.validate_type(file_path, 'File')
    @parameters[:file] = File.new(file_path, "r")
  end

  def file_path
    @parameters[:file].path rescue nil
  end

  def parse
    if url
      @doc = Nokogiri::XML(open(url))
    elsif file_path
      @doc = File.open(file_path) { |f| Nokogiri::XML(f) }
    end
    Validator.validate_nokogiri(@doc)
  end

  def doc
    @doc
  end

  def doi
    Validator.validate_nokogiri(@doc)
    expand_doi(@doc.xpath("//*/article-meta/article-id[@pub-id-type='doi']").text)
  end

  def title
    Validator.validate_nokogiri(@doc)
    t = @doc.xpath("//*/article-meta/title-group/article-title").text
    clean_text(t)
  end

  def abstract
    Validator.validate_nokogiri(@doc)
    a = @doc.xpath("//*/article-meta/abstract/*/p").text
    clean_text(a)
  end

  def keywords
    Validator.validate_nokogiri(@doc)
    @doc.xpath("//*/article-meta/kwd-group/kwd").map(&:text) rescue []
  end

  def authors
    Validator.validate_nokogiri(@doc)
    data = []
    @doc.xpath("//*/contrib[@contrib-type='author']").each do |author|
      rid = author.xpath("xref").attr("rid").value rescue nil
      affiliation = nil
      if !rid.nil?
        affiliation = clean_text(@doc.xpath("//*/aff[@id='#{rid}']/addr-line").text)
      end
      orcid = author.xpath("uri[@content-type='orcid']").text rescue nil
      given = clean_text(author.xpath("name/given-names").text)
      surname = clean_text(author.xpath("name/surname").text)
      data << { 
        given: given,
        surname: surname,
        fullname: [given, surname].join(" "),
        email: author.xpath("email").text,
        affiliation: affiliation,
        orcid: orcid
      }
    end
    data
  end

  def conference_part
    Validator.validate_nokogiri(@doc)
    coll = @doc.xpath("//*/subj-group[@subj-group-type='conference-part']/subject").text
    clean_text(coll)
  end
{'fraction_non_alphanumeric': 0.15195615195615195, 'fraction_numerical': 0.00189000189000189, 'mean_word_length': 2.888317413666422, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2429407', 'n_tokens_mistral': 1938, 'n_tokens_neox': 1864, 'n_words': 341}