<commit_before>module Nanoc
  class Compiler

    DEFAULT_CONFIG = {
      :output_dir   => 'output',
      :eruby_engine => 'erb'
    }

    FILE_TYPES = {
      '.erb'    => :eruby,
      '.rhtml'  => :eruby,
      '.haml'   => :haml,
      '.mab'    => :markaby,
      '.liquid' => :liquid
    }

    PAGE_DEFAULTS = {
      :custom_path  => nil,
      :filename     => 'index',
      :extension    => 'html',
      :filters      => [],
      :is_draft     => false,
      :layout       => 'default'
    }

    attr_reader :config, :stack, :pages

    def initialize
      @filters = {}
    end

    def run
      # Make sure we're in a nanoc site
      Nanoc.ensure_in_site

      # Load some configuration stuff
      @config      = DEFAULT_CONFIG.merge(YAML.load_file_and_clean('config.yaml'))
      @global_page = PAGE_DEFAULTS.merge(YAML.load_file_and_clean('meta.yaml'))

      # Require all Ruby source files in lib/
      Dir['lib/*.rb'].each { |f| require f }

      # Create output directory if necessary
      FileUtils.mkdir_p(@config[:output_dir])

      # Get all pages
      @pages = find_uncompiled_pages

      # Filter, layout, and filter again
      filter(:pre)
      layout
      filter(:post)

      # Save pages
      save_pages
    end

    # Filter management

    def register_filter(name, &block)
      @filters[name.to_sym] = block
    end

    def filter_named(name)
      @filters[name.to_sym]
    end

  private

    # Main methods

    def find_uncompiled_pages
      # Read all meta files
      Dir['content/**/meta.yaml'].inject([]) do |pages, filename|
        # Read the meta file
        hash = @global_page.merge(YAML.load_file_and_clean(filename))

        # Fix the path
        hash[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')

        # Convert to a Page instance
        page = Page.new(hash, self)

        # Get the content filename
        page.content_filename = content_filename_for_meta_filename(filename)

        # Skip drafts
        hash[:is_draft] ? pages : pages + [ page ]
      end
    end

    def filter(stage)
      # Reset filter stack
      @stack = []

      # Filter every page
      @pages.each do |page|
        page.stage        = stage
        page.is_filtered  = false
        page.filter!
      end
    end

    def layout
      # For each page (ignoring drafts)
      @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
        begin
          # Layout the page
          page.layout!
        rescue => exception
          handle_exception(exception, "layouting page '#{page.content_filename}' in layout '#{page.attributes[:layout]}'")
        end
      end
    end

    def save_pages
      @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
        # Write page with layout
        FileManager.create_file(page.path) { page.content }
      end
    end

    # Helper methods

    def content_filename_for_meta_filename(filename)
      # Find all files with base name of parent directory
      content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]

      # Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
      content_filenames += Dir["#{File.dirname(filename)}/index.*"]<commit_msg>fixed bug which could cause some page's stage not to be set before filtering<commit_after>module Nanoc
  class Compiler

    DEFAULT_CONFIG = {
      :output_dir   => 'output',
      :eruby_engine => 'erb'
    }

    FILE_TYPES = {
      '.erb'    => :eruby,
      '.rhtml'  => :eruby,
      '.haml'   => :haml,
      '.mab'    => :markaby,
      '.liquid' => :liquid
    }

    PAGE_DEFAULTS = {
      :custom_path  => nil,
      :filename     => 'index',
      :extension    => 'html',
      :filters      => [],
      :is_draft     => false,
      :layout       => 'default'
    }

    attr_reader :config, :stack, :pages

    def initialize
      @filters = {}
    end

    def run
      # Make sure we're in a nanoc site
      Nanoc.ensure_in_site

      # Load some configuration stuff
      @config      = DEFAULT_CONFIG.merge(YAML.load_file_and_clean('config.yaml'))
      @global_page = PAGE_DEFAULTS.merge(YAML.load_file_and_clean('meta.yaml'))

      # Require all Ruby source files in lib/
      Dir['lib/*.rb'].each { |f| require f }

      # Create output directory if necessary
      FileUtils.mkdir_p(@config[:output_dir])

      # Get all pages
      @pages = find_uncompiled_pages

      # Filter, layout, and filter again
      filter(:pre)
      layout
      filter(:post)

      # Save pages
      save_pages
    end

    # Filter management

    def register_filter(name, &block)
      @filters[name.to_sym] = block
    end

    def filter_named(name)
      @filters[name.to_sym]
    end

  private

    # Main methods

    def find_uncompiled_pages
      # Read all meta files
      Dir['content/**/meta.yaml'].inject([]) do |pages, filename|
        # Read the meta file
        hash = @global_page.merge(YAML.load_file_and_clean(filename))

        # Fix the path
        hash[:path] = filename.sub(/^content/, '').sub('meta.yaml', '')

        # Convert to a Page instance
        page = Page.new(hash, self)

        # Get the content filename
        page.content_filename = content_filename_for_meta_filename(filename)

        # Skip drafts
        hash[:is_draft] ? pages : pages + [ page ]
      end
    end

    def filter(stage)
      # Reset filter stack
      @stack = []

      # Prepare pages
      @pages.each do |page|
        page.stage        = stage
        page.is_filtered  = false
      end

      # Filter pages
      @pages.each { |page| page.filter! }
    end

    def layout
      # For each page (ignoring drafts)
      @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
        begin
          # Layout the page
          page.layout!
        rescue => exception
          handle_exception(exception, "layouting page '#{page.content_filename}' in layout '#{page.attributes[:layout]}'")
        end
      end
    end

    def save_pages
      @pages.reject { |page| page.attributes[:skip_output] }.each do |page|
        # Write page with layout
        FileManager.create_file(page.path) { page.content }
      end
    end

    # Helper methods

    def content_filename_for_meta_filename(filename)
      # Find all files with base name of parent directory
      content_filenames = Dir[filename.sub('meta.yaml', File.basename(File.dirname(filename)) + '.*')]

      # Find all index.* files (used to be a fallback for nanoc 1.0, kinda...)
      content_filenames += Dir["#{File.dirname(filename)}/index.*"]
{'fraction_non_alphanumeric': 0.11391644123835287, 'fraction_numerical': 0.0006011421701232341, 'mean_word_length': 2.1421152030217185, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, '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': '1266823', 'n_tokens_mistral': 2084, 'n_tokens_neox': 1992, 'n_words': 509}