<commit_before>
require 'ostruct'
require 'find'
require 'compass'
require 'ninesixty'
require 'time'

require 'hashery/opencascade'

require 'awestruct/config'
require 'awestruct/site'
require 'awestruct/haml_file'
require 'awestruct/erb_file'
require 'awestruct/textile_file'
require 'awestruct/markdown_file'
require 'awestruct/sass_file'
require 'awestruct/scss_file'
require 'awestruct/org_mode_file'
require 'awestruct/verbatim_file'

require 'awestruct/context_helper'

require 'awestruct/extensions/pipeline'
require 'awestruct/extensions/posts'
require 'awestruct/extensions/indexifier'
require 'awestruct/extensions/data_dir'
require 'awestruct/extensions/paginator'
require 'awestruct/extensions/atomizer'
require 'awestruct/extensions/tagger'
require 'awestruct/extensions/tag_cloud'
require 'awestruct/extensions/intense_debate'
require 'awestruct/extensions/disqus'
require 'awestruct/extensions/flattr'
require 'awestruct/extensions/google_analytics'
require 'awestruct/extensions/partial'

require 'awestruct/util/inflector'
require 'awestruct/util/default_inflections'

module Awestruct

  class Engine

    attr_reader :config
    attr_reader :dir
    attr_reader :site

    def initialize(config)
      @dir    = config.input_dir
      @config = config

      @site   = Site.new( config )
      @site.engine = self

      @helpers = []
      @max_site_mtime = nil
    end

    def skin_dir
      @site.skin_dir
    end

    def generate(profile=nil, base_url=nil, default_base_url=nil, force=false)
      @base_url         = base_url
      @default_base_url = default_base_url
      @max_site_mtime = nil
      load_site_yaml(profile)
      load_yamls
      set_base_url
      load_layouts
      load_pages
      load_extensions
      set_urls(site.pages)
      configure_compass
      generate_files(force)
    end

    def find_and_load_site_page(simple_path)
      path_glob = File.join( config.input_dir, simple_path + '.*' )
      candidates = Dir[ path_glob ]
      return nil if candidates.empty?
      throw Exception.new( "too many choices for #{simple_path}" ) if candidates.size != 1
      dir_pathname = Pathname.new( dir )
      path_name = Pathname.new( candidates[0] )
      relative_path = path_name.relative_path_from( dir_pathname ).to_s
      load_page( candidates[0], :relative_path => relative_path )
    end

    def load_site_page(relative_path)
      load_page( File.join( dir, relative_path ) )
    end

    def load_page(path, options = {})
      page = nil
      if ( options[:relative_path].nil? )
        #dir_pathname = Pathname.new( dir )
        #path_name = Pathname.new( path )
        #relative_path = path_name.relative_path_from( dir_pathname ).to_s
      end

      fixed_relative_path = ( options[:relative_path].nil? ? nil : File.join( '', options[:relative_path] ) )

      if ( path =~ /\.haml$/ )
        page = HamlFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.erb$/ )
        page = ErbFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.textile$/ )
        page = TextileFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.md$/ )
        page = MarkdownFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.sass$/ )
        page = SassFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.scss$/ )
        page = ScssFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.org$/ )
        page = OrgModeFile.new( site, path, fixed_relative_path, options )
      elsif ( File.file?( path ) )
        page = VerbatimFile.new( site, path, fixed_relative_path, options )
      end
      page
    end

    def create_context(page, content='')
      context = OpenStruct.new( :site=>site, :content=>content )
      context.extend( Awestruct::ContextHelper )
      @helpers.each do |h|
        context.extend( h )
      end
      context.page = page
      class << context
        def interpolate_string(str)
          if site.interpolate
            str = str || ''
            str = str.gsub( /\\/, '\\\\\\\\' )
            str = str.gsub( /\\\\#/, '\\#' )
            str = str.gsub( '@', '' ) #'\@' )
            str = "%@#{str}@"
            result = instance_eval( str )
            result
          else
            str || ''
          end
        end
        def evaluate_erb(erb)
          erb.result( binding )
        end
      end
      context
    end

  def set_urls(pages)
      pages.each do |page|
        page_path = page.output_path
        if ( page_path =~ /^\// )
          page.url = page_path
        else
          page.url = "/#{page_path}"
        end
        if ( page.url =~ /^(.*\/)index.html$/ )
          page.url = $1
        end
      end
    end

    private

    def configure_compass
      Compass.configuration.project_type    = :standalone
      Compass.configuration.project_path    = dir
      Compass.configuration.css_dir         = File.join( dir, config.output_dir, 'stylesheets' )
      Compass.configuration.sass_dir        = File.join( dir, 'stylesheets' )
      Compass.configuration.images_dir      = File.join( dir, 'images' )
      Compass.configuration.javascripts_dir = File.join( dir, 'javascripts' )
    end

    def set_base_url
      if ( @base_url )
        site.base_url = @base_url
      end

      if ( site.base_url.nil? )
        site.base_url = @default_base_url
      end

      if ( site.base_url )
        if ( site.base_url =~ /^(.*)\/$/ )
          site.base_url = $1
        end
      end
    end

    def generate_files(force)
      site.pages.each do |page|
        generate_page( page, force )
      end
    end

    def generate_page(page, force)
      return unless requires_generation?(page, force)<commit_msg>Fix Compass configuration, xxx_dir is relative to project_path<commit_after>
require 'ostruct'
require 'find'
require 'compass'
require 'ninesixty'
require 'time'

require 'hashery/opencascade'

require 'awestruct/config'
require 'awestruct/site'
require 'awestruct/haml_file'
require 'awestruct/erb_file'
require 'awestruct/textile_file'
require 'awestruct/markdown_file'
require 'awestruct/sass_file'
require 'awestruct/scss_file'
require 'awestruct/org_mode_file'
require 'awestruct/verbatim_file'

require 'awestruct/context_helper'

require 'awestruct/extensions/pipeline'
require 'awestruct/extensions/posts'
require 'awestruct/extensions/indexifier'
require 'awestruct/extensions/data_dir'
require 'awestruct/extensions/paginator'
require 'awestruct/extensions/atomizer'
require 'awestruct/extensions/tagger'
require 'awestruct/extensions/tag_cloud'
require 'awestruct/extensions/intense_debate'
require 'awestruct/extensions/disqus'
require 'awestruct/extensions/flattr'
require 'awestruct/extensions/google_analytics'
require 'awestruct/extensions/partial'

require 'awestruct/util/inflector'
require 'awestruct/util/default_inflections'

module Awestruct

  class Engine

    attr_reader :config
    attr_reader :dir
    attr_reader :site

    def initialize(config)
      @dir    = config.input_dir
      @config = config

      @site   = Site.new( config )
      @site.engine = self

      @helpers = []
      @max_site_mtime = nil
    end

    def skin_dir
      @site.skin_dir
    end

    def generate(profile=nil, base_url=nil, default_base_url=nil, force=false)
      @base_url         = base_url
      @default_base_url = default_base_url
      @max_site_mtime = nil
      load_site_yaml(profile)
      load_yamls
      set_base_url
      load_layouts
      load_pages
      load_extensions
      set_urls(site.pages)
      configure_compass
      generate_files(force)
    end

    def find_and_load_site_page(simple_path)
      path_glob = File.join( config.input_dir, simple_path + '.*' )
      candidates = Dir[ path_glob ]
      return nil if candidates.empty?
      throw Exception.new( "too many choices for #{simple_path}" ) if candidates.size != 1
      dir_pathname = Pathname.new( dir )
      path_name = Pathname.new( candidates[0] )
      relative_path = path_name.relative_path_from( dir_pathname ).to_s
      load_page( candidates[0], :relative_path => relative_path )
    end

    def load_site_page(relative_path)
      load_page( File.join( dir, relative_path ) )
    end

    def load_page(path, options = {})
      page = nil
      if ( options[:relative_path].nil? )
        #dir_pathname = Pathname.new( dir )
        #path_name = Pathname.new( path )
        #relative_path = path_name.relative_path_from( dir_pathname ).to_s
      end

      fixed_relative_path = ( options[:relative_path].nil? ? nil : File.join( '', options[:relative_path] ) )

      if ( path =~ /\.haml$/ )
        page = HamlFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.erb$/ )
        page = ErbFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.textile$/ )
        page = TextileFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.md$/ )
        page = MarkdownFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.sass$/ )
        page = SassFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.scss$/ )
        page = ScssFile.new( site, path, fixed_relative_path, options )
      elsif ( path =~ /\.org$/ )
        page = OrgModeFile.new( site, path, fixed_relative_path, options )
      elsif ( File.file?( path ) )
        page = VerbatimFile.new( site, path, fixed_relative_path, options )
      end
      page
    end

    def create_context(page, content='')
      context = OpenStruct.new( :site=>site, :content=>content )
      context.extend( Awestruct::ContextHelper )
      @helpers.each do |h|
        context.extend( h )
      end
      context.page = page
      class << context
        def interpolate_string(str)
          if site.interpolate
            str = str || ''
            str = str.gsub( /\\/, '\\\\\\\\' )
            str = str.gsub( /\\\\#/, '\\#' )
            str = str.gsub( '@', '' ) #'\@' )
            str = "%@#{str}@"
            result = instance_eval( str )
            result
          else
            str || ''
          end
        end
        def evaluate_erb(erb)
          erb.result( binding )
        end
      end
      context
    end

  def set_urls(pages)
      pages.each do |page|
        page_path = page.output_path
        if ( page_path =~ /^\// )
          page.url = page_path
        else
          page.url = "/#{page_path}"
        end
        if ( page.url =~ /^(.*\/)index.html$/ )
          page.url = $1
        end
      end
    end

    private

    def configure_compass
      Compass.configuration.project_type    = :standalone
      Compass.configuration.project_path    = dir
      Compass.configuration.css_dir         = File.join( config.output_dir, 'stylesheets' )
      Compass.configuration.sass_dir        = 'stylesheets'
      Compass.configuration.images_dir      = 'images'
      Compass.configuration.javascripts_dir = 'javascripts'
    end

    def set_base_url
      if ( @base_url )
        site.base_url = @base_url
      end

      if ( site.base_url.nil? )
        site.base_url = @default_base_url
      end

      if ( site.base_url )
        if ( site.base_url =~ /^(.*)\/$/ )
          site.base_url = $1
        end
      end
    end

    def generate_files(force)
      site.pages.each do |page|
        generate_page( page, force )
      end
    end

    def generate_page(page, force)
      return unless requires_generation?(page, force)
{'fraction_non_alphanumeric': 0.11047816330053513, 'fraction_numerical': 0.0008631106507854307, 'mean_word_length': 2.4331851851851853, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5795855', 'n_tokens_mistral': 3792, 'n_tokens_neox': 3705, 'n_words': 785}