fronde 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/bin/fronde +15 -30
 - data/lib/ext/nil_time.rb +25 -0
 - data/lib/ext/r18n.rb +17 -0
 - data/lib/ext/time.rb +49 -0
 - data/lib/fronde/cli/commands.rb +92 -103
 - data/lib/fronde/cli/data/Rakefile +8 -0
 - data/lib/fronde/cli/data/config.yml +13 -0
 - data/lib/fronde/cli/data/gitignore +7 -0
 - data/lib/fronde/cli/data/zsh_completion +37 -0
 - data/lib/fronde/cli/helpers.rb +55 -0
 - data/lib/fronde/cli/opt_parse.rb +143 -0
 - data/lib/fronde/cli/throbber.rb +99 -0
 - data/lib/fronde/cli.rb +41 -42
 - data/lib/fronde/config/data/org-config.el +24 -0
 - data/lib/fronde/config/{ox-fronde.el → data/ox-fronde.el} +1 -1
 - data/lib/fronde/config/helpers.rb +80 -0
 - data/lib/fronde/config/lisp.rb +70 -0
 - data/lib/fronde/config.rb +135 -99
 - data/lib/fronde/emacs.rb +23 -20
 - data/lib/fronde/index/atom_generator.rb +55 -66
 - data/lib/fronde/index/data/all_tags.org +14 -0
 - data/lib/fronde/index/data/template.org +22 -0
 - data/lib/fronde/index/data/template.xml +37 -0
 - data/lib/fronde/index/org_generator.rb +70 -88
 - data/lib/fronde/index.rb +56 -82
 - data/lib/fronde/org/file.rb +287 -0
 - data/lib/fronde/org/file_extracter.rb +98 -0
 - data/lib/fronde/org.rb +103 -0
 - data/lib/fronde/preview.rb +43 -39
 - data/lib/fronde/slug.rb +27 -0
 - data/lib/fronde/source/gemini.rb +39 -0
 - data/lib/fronde/source/html.rb +67 -0
 - data/lib/fronde/source.rb +204 -0
 - data/lib/fronde/templater.rb +94 -71
 - data/lib/fronde/version.rb +1 -1
 - data/lib/tasks/cli.rake +33 -0
 - data/lib/tasks/org.rake +63 -43
 - data/lib/tasks/site.rake +68 -30
 - data/lib/tasks/sync.rake +41 -21
 - data/lib/tasks/tags.rake +11 -7
 - data/locales/en.yml +60 -14
 - data/locales/fr.yml +68 -14
 - metadata +57 -156
 - data/lib/fronde/config/lisp_config.rb +0 -340
 - data/lib/fronde/config/org-config.el +0 -19
 - data/lib/fronde/org_file/class_methods.rb +0 -72
 - data/lib/fronde/org_file/extracter.rb +0 -72
 - data/lib/fronde/org_file/htmlizer.rb +0 -43
 - data/lib/fronde/org_file.rb +0 -298
 - data/lib/fronde/utils.rb +0 -229
 
| 
         @@ -0,0 +1,67 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Fronde
         
     | 
| 
      
 4 
     | 
    
         
            +
              class Source
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Specific settings for HTML {Fronde::Source}
         
     | 
| 
      
 6 
     | 
    
         
            +
                class Html < Source
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def org_config
         
     | 
| 
      
 8 
     | 
    
         
            +
                    config = super
         
     | 
| 
      
 9 
     | 
    
         
            +
                    config[0]['theme'] = @config['theme']
         
     | 
| 
      
 10 
     | 
    
         
            +
                    config
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 14 
     | 
    
         
            +
                    def org_default_postamble
         
     | 
| 
      
 15 
     | 
    
         
            +
                      <<~POSTAMBLE
         
     | 
| 
      
 16 
     | 
    
         
            +
                        <p><span class="author">#{R18n.t.fronde.org.postamble.written_by}</span>
         
     | 
| 
      
 17 
     | 
    
         
            +
                        #{R18n.t.fronde.org.postamble.with_emacs_html}</p>
         
     | 
| 
      
 18 
     | 
    
         
            +
                        <p class="date">#{R18n.t.fronde.org.postamble.last_modification}</p>
         
     | 
| 
      
 19 
     | 
    
         
            +
                        <p class="validation">%v</p>
         
     | 
| 
      
 20 
     | 
    
         
            +
                      POSTAMBLE
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  private
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def fill_in_specific_config
         
     | 
| 
      
 27 
     | 
    
         
            +
                    @config.merge!(
         
     | 
| 
      
 28 
     | 
    
         
            +
                      'type' => 'html', 'ext' => '.html', 'mime_type' => 'text/html',
         
     | 
| 
      
 29 
     | 
    
         
            +
                      'folder' => CONFIG.get('html_public_folder')
         
     | 
| 
      
 30 
     | 
    
         
            +
                    )
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def org_publish_options
         
     | 
| 
      
 34 
     | 
    
         
            +
                    if @config['is_blog']
         
     | 
| 
      
 35 
     | 
    
         
            +
                      @config['atom_feed'] = <<~ATOMFEED
         
     | 
| 
      
 36 
     | 
    
         
            +
                        <link rel="alternate" type="application/atom+xml" title="#{@config['title']}"
         
     | 
| 
      
 37 
     | 
    
         
            +
                              href="#{@config['domain']}#{public_absolute_path}feeds/index.xml" />
         
     | 
| 
      
 38 
     | 
    
         
            +
                      ATOMFEED
         
     | 
| 
      
 39 
     | 
    
         
            +
                    end
         
     | 
| 
      
 40 
     | 
    
         
            +
                    super
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  def org_default_options # rubocop:disable Metrics/MethodLength
         
     | 
| 
      
 44 
     | 
    
         
            +
                    defaults = {
         
     | 
| 
      
 45 
     | 
    
         
            +
                      'publishing-function' => 'org-html-publish-to-html',
         
     | 
| 
      
 46 
     | 
    
         
            +
                      'html-head-include-default-style' => 't',
         
     | 
| 
      
 47 
     | 
    
         
            +
                      'html-head-include-scripts' => 't',
         
     | 
| 
      
 48 
     | 
    
         
            +
                      'html-head' => '{{ atom_feed }}',
         
     | 
| 
      
 49 
     | 
    
         
            +
                      'html-postamble' => Html.org_default_postamble
         
     | 
| 
      
 50 
     | 
    
         
            +
                    }
         
     | 
| 
      
 51 
     | 
    
         
            +
                    return defaults if @config['theme'] == 'default'
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                    defaults.merge(
         
     | 
| 
      
 54 
     | 
    
         
            +
                      'html-head-include-default-style' => 'nil',
         
     | 
| 
      
 55 
     | 
    
         
            +
                      'html-head-include-scripts' => 'nil',
         
     | 
| 
      
 56 
     | 
    
         
            +
                      'html-head' => <<~HTMLHEAD
         
     | 
| 
      
 57 
     | 
    
         
            +
                        <link rel="stylesheet" type="text/css" media="screen"
         
     | 
| 
      
 58 
     | 
    
         
            +
                              href="{{ domain }}/assets/{{ theme }}/css/style.css">
         
     | 
| 
      
 59 
     | 
    
         
            +
                        <link rel="stylesheet" type="text/css" media="screen"
         
     | 
| 
      
 60 
     | 
    
         
            +
                              href="{{ domain }}/assets/{{ theme }}/css/htmlize.css">
         
     | 
| 
      
 61 
     | 
    
         
            +
                        {{ atom_feed }}
         
     | 
| 
      
 62 
     | 
    
         
            +
                      HTMLHEAD
         
     | 
| 
      
 63 
     | 
    
         
            +
                    )
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
              end
         
     | 
| 
      
 67 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,204 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Fronde
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Wrapper for each possible project source.
         
     | 
| 
      
 5 
     | 
    
         
            +
              # Must be subclassed by specific source type (like Gemini or HTML)
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Source
         
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(source_config)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @config = {
         
     | 
| 
      
 9 
     | 
    
         
            +
                    'recursive' => true, 'is_blog' => false,
         
     | 
| 
      
 10 
     | 
    
         
            +
                    'domain' => CONFIG.get('domain'), 'atom_feed' => '',
         
     | 
| 
      
 11 
     | 
    
         
            +
                    'org-options' => {
         
     | 
| 
      
 12 
     | 
    
         
            +
                      'section-numbers' => 'nil', 'with-toc' => 'nil'
         
     | 
| 
      
 13 
     | 
    
         
            +
                    }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  }.merge(source_config)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  clean_config
         
     | 
| 
      
 16 
     | 
    
         
            +
                  org_publish_options
         
     | 
| 
      
 17 
     | 
    
         
            +
                  render_heading
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def [](key)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @config[key]
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def []=(key, value)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @config[key] = value
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def type
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @config['type']
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                def recursive?
         
     | 
| 
      
 33 
     | 
    
         
            +
                  !!@config['recursive']
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def blog?
         
     | 
| 
      
 37 
     | 
    
         
            +
                  !!@config['is_blog']
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def to_h
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @config
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def source_for?(file_name)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  relative_file_path = file_name.delete_prefix "#{@config['path']}/"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  # file_name does not begin with source path.
         
     | 
| 
      
 47 
     | 
    
         
            +
                  return false if relative_file_path == file_name
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  # Looks like a file at a deeper level, but current source is not
         
     | 
| 
      
 50 
     | 
    
         
            +
                  # recursive.
         
     | 
| 
      
 51 
     | 
    
         
            +
                  return false if relative_file_path.include?('/') && !recursive?
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  # We don’t check file if the file really exist as the current
         
     | 
| 
      
 54 
     | 
    
         
            +
                  # check may be done before the file is actually written.
         
     | 
| 
      
 55 
     | 
    
         
            +
                  true
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def source_for(file_name)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  relative_file_path = file_name.delete_prefix "#{publication_path}/"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  # file_name does not begin with source path.
         
     | 
| 
      
 61 
     | 
    
         
            +
                  return nil if relative_file_path == file_name
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  # Looks like a file at a deeper level, but current source is not
         
     | 
| 
      
 64 
     | 
    
         
            +
                  # recursive.
         
     | 
| 
      
 65 
     | 
    
         
            +
                  return nil if relative_file_path.include?('/') && !recursive?
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                  # Looks like a match. But does a source file for this one actually
         
     | 
| 
      
 68 
     | 
    
         
            +
                  # exists?
         
     | 
| 
      
 69 
     | 
    
         
            +
                  relative_source_path = relative_file_path.sub(
         
     | 
| 
      
 70 
     | 
    
         
            +
                    /#{@config['ext']}\z/, '.org'
         
     | 
| 
      
 71 
     | 
    
         
            +
                  )
         
     | 
| 
      
 72 
     | 
    
         
            +
                  source_path = File.join(@config['path'], relative_source_path)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  return nil unless File.file?(source_path)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  source_path
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def target_for(file_name)
         
     | 
| 
      
 79 
     | 
    
         
            +
                  target = File.expand_path file_name
         
     | 
| 
      
 80 
     | 
    
         
            +
                  target.delete_prefix! "#{Dir.pwd}/"
         
     | 
| 
      
 81 
     | 
    
         
            +
                  target.sub!(/\.org\z/, @config['ext'])
         
     | 
| 
      
 82 
     | 
    
         
            +
                  project_relative_path = @config['path'].delete_prefix("#{Dir.pwd}/")
         
     | 
| 
      
 83 
     | 
    
         
            +
                  target.delete_prefix! "#{project_relative_path}/"
         
     | 
| 
      
 84 
     | 
    
         
            +
                  public_absolute_path + target
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                def exclude_file?(file_name)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  # Obviously excluding index itself for blogs
         
     | 
| 
      
 89 
     | 
    
         
            +
                  return true if file_name == File.join(@config['path'], 'index.org')
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  exclusion_rules = @config['exclude']
         
     | 
| 
      
 92 
     | 
    
         
            +
                  return false unless exclusion_rules
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  file_name.match? exclusion_rules
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                def org_config
         
     | 
| 
      
 98 
     | 
    
         
            +
                  name = @config['name']
         
     | 
| 
      
 99 
     | 
    
         
            +
                  [{ 'name' => name, 'attributes' => org_project_config },
         
     | 
| 
      
 100 
     | 
    
         
            +
                   { 'name' => "#{name}-assets", 'attributes' => org_assets_config }]
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                # Return the publication absolute path on file system.
         
     | 
| 
      
 104 
     | 
    
         
            +
                #
         
     | 
| 
      
 105 
     | 
    
         
            +
                # The returned string never end with a slash (/).
         
     | 
| 
      
 106 
     | 
    
         
            +
                #
         
     | 
| 
      
 107 
     | 
    
         
            +
                # Use {Fronde::Source#public_absolute_path} to get the absolute path
         
     | 
| 
      
 108 
     | 
    
         
            +
                # of this project, as seen from a web browser.
         
     | 
| 
      
 109 
     | 
    
         
            +
                #
         
     | 
| 
      
 110 
     | 
    
         
            +
                # @return [String] the absolute path to the target dir of this project
         
     | 
| 
      
 111 
     | 
    
         
            +
                def publication_path
         
     | 
| 
      
 112 
     | 
    
         
            +
                  return @config['publication_path'] if @config['publication_path']
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  publish_in = [File.expand_path(@config['folder']), @config['target']]
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @config['publication_path'] = publish_in.join('/').delete_suffix('/')
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                # Return the absolute path as seen in User Agent.
         
     | 
| 
      
 119 
     | 
    
         
            +
                #
         
     | 
| 
      
 120 
     | 
    
         
            +
                # The returned string always end with a slash (/).
         
     | 
| 
      
 121 
     | 
    
         
            +
                #
         
     | 
| 
      
 122 
     | 
    
         
            +
                # Use {Fronde::Source#publication_path} to locate published file on
         
     | 
| 
      
 123 
     | 
    
         
            +
                # the file system.
         
     | 
| 
      
 124 
     | 
    
         
            +
                #
         
     | 
| 
      
 125 
     | 
    
         
            +
                # @return [String] the absolute path to this project
         
     | 
| 
      
 126 
     | 
    
         
            +
                def public_absolute_path
         
     | 
| 
      
 127 
     | 
    
         
            +
                  return @config['public_absolute_path'] if @config['public_absolute_path']
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                  @config['public_absolute_path'] = "/#{@config['target']}/".squeeze('/')
         
     | 
| 
      
 130 
     | 
    
         
            +
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 133 
     | 
    
         
            +
                  def canonical_config(config)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    config = { 'path' => config } if config.is_a?(String)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    config['type'] ||= 'html'
         
     | 
| 
      
 136 
     | 
    
         
            +
                    config
         
     | 
| 
      
 137 
     | 
    
         
            +
                  end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  def new_from_config(config)
         
     | 
| 
      
 140 
     | 
    
         
            +
                    klass_name = config['type'].capitalize
         
     | 
| 
      
 141 
     | 
    
         
            +
                    klass = Kernel.const_get("::Fronde::Source::#{klass_name}")
         
     | 
| 
      
 142 
     | 
    
         
            +
                    klass.new(config)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                private
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                def clean_config
         
     | 
| 
      
 149 
     | 
    
         
            +
                  fill_in_specific_config
         
     | 
| 
      
 150 
     | 
    
         
            +
                  @config['name'] ||= @config['path'].sub(/^[.~]*\//, '').tr('/.', '-')
         
     | 
| 
      
 151 
     | 
    
         
            +
                  @config['title'] ||= @config['path']
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @config['target'] ||= File.basename(@config['path']).delete_prefix '.'
         
     | 
| 
      
 153 
     | 
    
         
            +
                  @config['target'] = '' if @config['target'] == '.'
         
     | 
| 
      
 154 
     | 
    
         
            +
                  @config['path'] = File.expand_path(@config['path'])
         
     | 
| 
      
 155 
     | 
    
         
            +
                  @config['theme'] ||= CONFIG.get('theme', 'default')
         
     | 
| 
      
 156 
     | 
    
         
            +
                  # Blog are necessarily recursive to allow publication of tags and feeds
         
     | 
| 
      
 157 
     | 
    
         
            +
                  @config['recursive'] = true if @config['is_blog']
         
     | 
| 
      
 158 
     | 
    
         
            +
                end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                def org_publish_options
         
     | 
| 
      
 161 
     | 
    
         
            +
                  type = @config['type']
         
     | 
| 
      
 162 
     | 
    
         
            +
                  options = org_default_options.merge(
         
     | 
| 
      
 163 
     | 
    
         
            +
                    @config['org-options'],
         
     | 
| 
      
 164 
     | 
    
         
            +
                    CONFIG.get("org-#{type}", {}),
         
     | 
| 
      
 165 
     | 
    
         
            +
                    @config["org-#{type}"] || {}
         
     | 
| 
      
 166 
     | 
    
         
            +
                  )
         
     | 
| 
      
 167 
     | 
    
         
            +
                  @config['org-options'] = options
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                def render_heading
         
     | 
| 
      
 171 
     | 
    
         
            +
                  heading_key = "#{@config['type']}-head"
         
     | 
| 
      
 172 
     | 
    
         
            +
                  heading = @config.dig 'org-options', heading_key
         
     | 
| 
      
 173 
     | 
    
         
            +
                  @config['org-options'][heading_key] = \
         
     | 
| 
      
 174 
     | 
    
         
            +
                    Config::Helpers.render_liquid_template(
         
     | 
| 
      
 175 
     | 
    
         
            +
                      heading, to_h
         
     | 
| 
      
 176 
     | 
    
         
            +
                    )
         
     | 
| 
      
 177 
     | 
    
         
            +
                end
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                def org_project_config
         
     | 
| 
      
 180 
     | 
    
         
            +
                  attributes = {
         
     | 
| 
      
 181 
     | 
    
         
            +
                    'base-directory' => @config['path'],
         
     | 
| 
      
 182 
     | 
    
         
            +
                    'base-extension' => 'org',
         
     | 
| 
      
 183 
     | 
    
         
            +
                    'publishing-directory' => publication_path,
         
     | 
| 
      
 184 
     | 
    
         
            +
                    'recursive' => @config['recursive']
         
     | 
| 
      
 185 
     | 
    
         
            +
                  }.merge(@config['org-options'])
         
     | 
| 
      
 186 
     | 
    
         
            +
                  exclude = @config['exclude']
         
     | 
| 
      
 187 
     | 
    
         
            +
                  attributes['exclude'] = exclude if exclude
         
     | 
| 
      
 188 
     | 
    
         
            +
                  attributes.sort.to_h # Have lisp config sorted
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                def org_assets_config
         
     | 
| 
      
 192 
     | 
    
         
            +
                  {
         
     | 
| 
      
 193 
     | 
    
         
            +
                    'base-directory' => @config['path'],
         
     | 
| 
      
 194 
     | 
    
         
            +
                    'base-extension' => %w[gif jpg png svg pdf].join('\\\\|'),
         
     | 
| 
      
 195 
     | 
    
         
            +
                    'publishing-directory' => publication_path,
         
     | 
| 
      
 196 
     | 
    
         
            +
                    'publishing-function' => 'org-publish-attachment',
         
     | 
| 
      
 197 
     | 
    
         
            +
                    'recursive' => @config['recursive']
         
     | 
| 
      
 198 
     | 
    
         
            +
                  }
         
     | 
| 
      
 199 
     | 
    
         
            +
                end
         
     | 
| 
      
 200 
     | 
    
         
            +
              end
         
     | 
| 
      
 201 
     | 
    
         
            +
            end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
            require_relative 'source/gemini'
         
     | 
| 
      
 204 
     | 
    
         
            +
            require_relative 'source/html'
         
     | 
    
        data/lib/fronde/templater.rb
    CHANGED
    
    | 
         @@ -2,117 +2,140 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'nokogiri'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'digest/md5'
         
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'org/file'
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            module Fronde
         
     | 
| 
      
 8 
     | 
    
         
            +
              class NoHeadError < ::StandardError; end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       8 
10 
     | 
    
         
             
              # Insert custom part inside generated HTML files.
         
     | 
| 
       9 
11 
     | 
    
         
             
              class Templater
         
     | 
| 
       10 
     | 
    
         
            -
                def initialize(source, dom,  
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(source, dom, config = {})
         
     | 
| 
       11 
13 
     | 
    
         
             
                  @dom = dom
         
     | 
| 
       12 
14 
     | 
    
         
             
                  @org_file = source
         
     | 
| 
       13 
     | 
    
         
            -
                  @ 
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
                  @ 
     | 
| 
       16 
     | 
    
         
            -
                  digest = Digest::MD5.hexdigest(@content)
         
     | 
| 
       17 
     | 
    
         
            -
                  @check_line = " Fronde Template: #{digest} "
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @config = { 'type' => 'after' }.merge(config)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  digest = Digest::MD5.hexdigest(config.to_s)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @config['check_line'] = " Fronde Template: #{digest} "
         
     | 
| 
       18 
18 
     | 
    
         
             
                end
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                def apply
         
     | 
| 
       21 
     | 
    
         
            -
                   
     | 
| 
       22 
     | 
    
         
            -
                   
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
      
 21 
     | 
    
         
            +
                  # Flag the file for this template
         
     | 
| 
      
 22 
     | 
    
         
            +
                  head = @dom.xpath('//head').first
         
     | 
| 
      
 23 
     | 
    
         
            +
                  raise NoHeadError, self unless head
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                  head.prepend_child("<!--#{@config['check_line']}-->")
         
     | 
| 
      
 26 
     | 
    
         
            +
                  content = @org_file.format extract_content
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # Remove source element if necessary to avoid doubling it during
         
     | 
| 
      
 28 
     | 
    
         
            +
                  # the insert action
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @config['source'].unlink if @config.has_key? 'source'
         
     | 
| 
      
 30 
     | 
    
         
            +
                  # Insert new content
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @dom.css(@config['selector']).each do |element|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    insert_new_node_at element, content
         
     | 
| 
       25 
33 
     | 
    
         
             
                  end
         
     | 
| 
       26 
34 
     | 
    
         
             
                end
         
     | 
| 
       27 
35 
     | 
    
         | 
| 
       28 
36 
     | 
    
         
             
                def in_head?
         
     | 
| 
       29 
     | 
    
         
            -
                  @dom.xpath('//head').children. 
     | 
| 
       30 
     | 
    
         
            -
                     
     | 
| 
      
 37 
     | 
    
         
            +
                  @dom.xpath('//head').children.any? do |child|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    next false unless child.comment?
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                    child.text == @config['check_line']
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                def valid?(file_name)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  return false unless @config.has_key?('selector')
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  unless @config.has_key?('content') || @config.has_key?('source')
         
     | 
| 
      
 48 
     | 
    
         
            +
                    return false
         
     | 
| 
       31 
49 
     | 
    
         
             
                  end
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  check_path(file_name)
         
     | 
| 
       33 
52 
     | 
    
         
             
                end
         
     | 
| 
       34 
53 
     | 
    
         | 
| 
       35 
54 
     | 
    
         
             
                class << self
         
     | 
| 
       36 
     | 
    
         
            -
                  def customize_output(file_name 
     | 
| 
       37 
     | 
    
         
            -
                     
     | 
| 
       38 
     | 
    
         
            -
                     
     | 
| 
       39 
     | 
    
         
            -
                    if source. 
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                      source = Fronde::OrgFile.new(sourcepath)
         
     | 
| 
       42 
     | 
    
         
            -
                    end
         
     | 
| 
      
 55 
     | 
    
         
            +
                  def customize_output(file_name)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    source = Fronde::Org::File.new(file_name)
         
     | 
| 
      
 57 
     | 
    
         
            +
                    # Return if no org file found for this published file
         
     | 
| 
      
 58 
     | 
    
         
            +
                    return if source.file.end_with?(file_name)
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
       43 
60 
     | 
    
         
             
                    dom = open_dom(file_name)
         
     | 
| 
       44 
     | 
    
         
            -
                     
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                      next if tpl.in_head?
         
     | 
| 
       47 
     | 
    
         
            -
                      tpl.apply
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
                    write_dom(file_name, dom)
         
     | 
| 
      
 61 
     | 
    
         
            +
                    updated = apply_templates(source, dom, file_name)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    write_dom(file_name, dom) if updated
         
     | 
| 
       50 
63 
     | 
    
         
             
                  end
         
     | 
| 
       51 
64 
     | 
    
         | 
| 
       52 
65 
     | 
    
         
             
                  private
         
     | 
| 
       53 
66 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
                  def  
     | 
| 
       55 
     | 
    
         
            -
                     
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                  def apply_templates(source, dom, file_name)
         
     | 
| 
      
 68 
     | 
    
         
            +
                    Fronde::CONFIG.get('templates', []).map do |config|
         
     | 
| 
      
 69 
     | 
    
         
            +
                      template = Fronde::Templater.new(source, dom, config)
         
     | 
| 
      
 70 
     | 
    
         
            +
                      next if !template.valid?(file_name) || template.in_head?
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                      template.apply
         
     | 
| 
      
 73 
     | 
    
         
            +
                      true
         
     | 
| 
      
 74 
     | 
    
         
            +
                    rescue NoHeadError
         
     | 
| 
      
 75 
     | 
    
         
            +
                      warn R18n.t.fronde.error.templater.no_head_element(file: file_name)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      next
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end.any?
         
     | 
| 
       58 
78 
     | 
    
         
             
                  end
         
     | 
| 
       59 
79 
     | 
    
         | 
| 
       60 
80 
     | 
    
         
             
                  def open_dom(file_name)
         
     | 
| 
       61 
     | 
    
         
            -
                     
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
                     
     | 
| 
       64 
     | 
    
         
            -
                    dom
         
     | 
| 
      
 81 
     | 
    
         
            +
                    File.open(file_name, 'r') do |file|
         
     | 
| 
      
 82 
     | 
    
         
            +
                      Nokogiri::HTML file
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
       65 
84 
     | 
    
         
             
                  end
         
     | 
| 
       66 
85 
     | 
    
         | 
| 
       67 
86 
     | 
    
         
             
                  def write_dom(file_name, dom)
         
     | 
| 
       68 
     | 
    
         
            -
                     
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
                    file.close
         
     | 
| 
       71 
     | 
    
         
            -
                  end
         
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
                  def check_path(file_name, pathes)
         
     | 
| 
       74 
     | 
    
         
            -
                    pub_folder = Fronde::Config.get('public_folder')
         
     | 
| 
       75 
     | 
    
         
            -
                    if pathes.is_a?(Array)
         
     | 
| 
       76 
     | 
    
         
            -
                      pathes.each do |tp|
         
     | 
| 
       77 
     | 
    
         
            -
                        return true if File.fnmatch?("#{pub_folder}#{tp}",
         
     | 
| 
       78 
     | 
    
         
            -
                                                     file_name, File::FNM_DOTMATCH)
         
     | 
| 
       79 
     | 
    
         
            -
                      end
         
     | 
| 
       80 
     | 
    
         
            -
                      return false
         
     | 
| 
      
 87 
     | 
    
         
            +
                    File.open(file_name, 'w') do |file|
         
     | 
| 
      
 88 
     | 
    
         
            +
                      dom.write_to file
         
     | 
| 
       81 
89 
     | 
    
         
             
                    end
         
     | 
| 
       82 
     | 
    
         
            -
                    File.fnmatch?("#{pub_folder}#{pathes}",
         
     | 
| 
       83 
     | 
    
         
            -
                                  file_name, File::FNM_DOTMATCH)
         
     | 
| 
       84 
     | 
    
         
            -
                  end
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                  def check_required_keys(opts, file_name)
         
     | 
| 
       87 
     | 
    
         
            -
                    return false unless opts.has_key?('selector')
         
     | 
| 
       88 
     | 
    
         
            -
                    return false unless opts.has_key?('content') || opts.has_key?('source')
         
     | 
| 
       89 
     | 
    
         
            -
                    return check_path(file_name, opts['path']) if opts.has_key?('path')
         
     | 
| 
       90 
     | 
    
         
            -
                    true
         
     | 
| 
       91 
90 
     | 
    
         
             
                  end
         
     | 
| 
       92 
91 
     | 
    
         
             
                end
         
     | 
| 
       93 
92 
     | 
    
         | 
| 
       94 
93 
     | 
    
         
             
                private
         
     | 
| 
       95 
94 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
                def  
     | 
| 
       97 
     | 
    
         
            -
                  @ 
     | 
| 
       98 
     | 
    
         
            -
                end
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
                def insert_new_node_at(elem, content)
         
     | 
| 
       101 
     | 
    
         
            -
                  case @position
         
     | 
| 
      
 95 
     | 
    
         
            +
                def insert_new_node_at(element, content)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  case @config['type']
         
     | 
| 
       102 
97 
     | 
    
         
             
                  when 'before'
         
     | 
| 
       103 
     | 
    
         
            -
                     
     | 
| 
      
 98 
     | 
    
         
            +
                    element.add_previous_sibling content
         
     | 
| 
       104 
99 
     | 
    
         
             
                  when 'replace'
         
     | 
| 
       105 
     | 
    
         
            -
                     
     | 
| 
      
 100 
     | 
    
         
            +
                    element.replace content
         
     | 
| 
       106 
101 
     | 
    
         
             
                  else
         
     | 
| 
       107 
     | 
    
         
            -
                     
     | 
| 
      
 102 
     | 
    
         
            +
                    element.add_next_sibling content
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                def extract_content
         
     | 
| 
      
 107 
     | 
    
         
            +
                  # We must either have a source or a content key
         
     | 
| 
      
 108 
     | 
    
         
            +
                  source = @config.delete 'source'
         
     | 
| 
      
 109 
     | 
    
         
            +
                  unless source.is_a?(String) && source != ''
         
     | 
| 
      
 110 
     | 
    
         
            +
                    return @config['content'] || ''
         
     | 
| 
      
 111 
     | 
    
         
            +
                  end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                  node = @dom.css(source)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  # Do nothing if we don’t have a reliable content to work with
         
     | 
| 
      
 115 
     | 
    
         
            +
                  unless node.any?
         
     | 
| 
      
 116 
     | 
    
         
            +
                    warn(
         
     | 
| 
      
 117 
     | 
    
         
            +
                      R18n.t.fronde.error.templater.no_element_found(
         
     | 
| 
      
 118 
     | 
    
         
            +
                        source: source,
         
     | 
| 
      
 119 
     | 
    
         
            +
                        file: Fronde::CONFIG.get('html_public_folder') + @org_file.pub_file
         
     | 
| 
      
 120 
     | 
    
         
            +
                      )
         
     | 
| 
      
 121 
     | 
    
         
            +
                    )
         
     | 
| 
      
 122 
     | 
    
         
            +
                    return ''
         
     | 
| 
       108 
123 
     | 
    
         
             
                  end
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  @config['source'] = node
         
     | 
| 
      
 126 
     | 
    
         
            +
                  node.to_s
         
     | 
| 
       109 
127 
     | 
    
         
             
                end
         
     | 
| 
       110 
128 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                def  
     | 
| 
       112 
     | 
    
         
            -
                   
     | 
| 
       113 
     | 
    
         
            -
                   
     | 
| 
       114 
     | 
    
         
            -
             
     | 
| 
       115 
     | 
    
         
            -
                   
     | 
| 
      
 129 
     | 
    
         
            +
                def check_path(file_name)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  paths = @config['path']
         
     | 
| 
      
 131 
     | 
    
         
            +
                  return true unless paths
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                  paths = [paths] unless paths.is_a? Array
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                  pub_folder = Fronde::CONFIG.get('html_public_folder')
         
     | 
| 
      
 136 
     | 
    
         
            +
                  paths.any? do |template_path|
         
     | 
| 
      
 137 
     | 
    
         
            +
                    File.fnmatch?("#{pub_folder}#{template_path}", file_name)
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
       116 
139 
     | 
    
         
             
                end
         
     | 
| 
       117 
140 
     | 
    
         
             
              end
         
     | 
| 
       118 
141 
     | 
    
         
             
            end
         
     | 
    
        data/lib/fronde/version.rb
    CHANGED
    
    
    
        data/lib/tasks/cli.rake
    ADDED
    
    | 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative '../fronde/cli/opt_parse'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            namespace :cli do
         
     | 
| 
      
 6 
     | 
    
         
            +
              desc 'Generate an autocomplete file for zsh'
         
     | 
| 
      
 7 
     | 
    
         
            +
              task :zsh_complete do
         
     | 
| 
      
 8 
     | 
    
         
            +
                data = {}
         
     | 
| 
      
 9 
     | 
    
         
            +
                all_commands = Fronde::CLI::OptParse::FRONDE_COMMANDS
         
     | 
| 
      
 10 
     | 
    
         
            +
                data['commands'] = all_commands.filter_map do |command, options|
         
     | 
| 
      
 11 
     | 
    
         
            +
                  next if options[:alias] || command == 'basic'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  opts = (options[:opts] || []).map do |opt|
         
     | 
| 
      
 14 
     | 
    
         
            +
                    opt_config = Fronde::CLI::OptParse::FRONDE_OPTIONS[opt]
         
     | 
| 
      
 15 
     | 
    
         
            +
                    keyword = nil
         
     | 
| 
      
 16 
     | 
    
         
            +
                    unless opt_config[:boolean]
         
     | 
| 
      
 17 
     | 
    
         
            +
                      keyword = opt_config[:keyword] || opt_config[:long].upcase
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                    { 'short' => opt,
         
     | 
| 
      
 20 
     | 
    
         
            +
                      'long' => "--#{opt_config[:long]}",
         
     | 
| 
      
 21 
     | 
    
         
            +
                      'keyword' => keyword }
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  translation = R18n.t.fronde.bin.commands[command].tr("'", '’')
         
     | 
| 
      
 25 
     | 
    
         
            +
                  { 'name' => command,
         
     | 
| 
      
 26 
     | 
    
         
            +
                    'translation' => translation,
         
     | 
| 
      
 27 
     | 
    
         
            +
                    'options' => opts }
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
                source = File.expand_path '../fronde/cli/data/zsh_completion', __dir__
         
     | 
| 
      
 30 
     | 
    
         
            +
                template = Liquid::Template.parse(File.read(source))
         
     | 
| 
      
 31 
     | 
    
         
            +
                puts template.render(data)
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/tasks/org.rake
    CHANGED
    
    | 
         @@ -2,61 +2,57 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'open-uri'
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative '../fronde/config'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative '../fronde/cli/throbber'
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            require 'rake/clean'
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            CLOBBER.push(
         
     | 
| 
       11 
     | 
    
         
            -
              'var/ 
     | 
| 
       12 
     | 
    
         
            -
              ' 
     | 
| 
      
 11 
     | 
    
         
            +
              'var/lib/org-config.el', '.dir-locals.el',
         
     | 
| 
      
 12 
     | 
    
         
            +
              'lib/htmlize.el'
         
     | 
| 
       13 
13 
     | 
    
         
             
            )
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            def make_org_cmd(org_dir, target)
         
     | 
| 
       16 
     | 
    
         
            -
              make = ['make', '-C', org_dir, target]
         
     | 
| 
       17 
     | 
    
         
            -
              return make.join(' ') if verbose
         
     | 
| 
       18 
     | 
    
         
            -
              make.insert(3, '-s')
         
     | 
| 
       19 
     | 
    
         
            -
              make << 'EMACSQ="emacs -Q --eval \'(setq inhibit-message t)\'"'
         
     | 
| 
       20 
     | 
    
         
            -
              make.join(' ')
         
     | 
| 
       21 
     | 
    
         
            -
            end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
15 
     | 
    
         
             
            namespace :org do
         
     | 
| 
       24 
16 
     | 
    
         
             
              directory 'var/tmp'
         
     | 
| 
       25 
17 
     | 
    
         | 
| 
       26 
18 
     | 
    
         
             
              desc 'Download last version of Org'
         
     | 
| 
       27 
19 
     | 
    
         
             
              file 'var/tmp/org.tar.gz' => 'var/tmp' do
         
     | 
| 
       28 
     | 
    
         
            -
                 
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
      
 20 
     | 
    
         
            +
                # Weird Rake issue, still executing the task even if the file exists
         
     | 
| 
      
 21 
     | 
    
         
            +
                next if File.exist? 'var/tmp/org.tar.gz'
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                download = Thread.new { Fronde::Org.download }
         
     | 
| 
       32 
24 
     | 
    
         
             
                if verbose
         
     | 
| 
       33 
     | 
    
         
            -
                  download. 
     | 
| 
       34 
     | 
    
         
            -
                  warn "Org version #{download[:org_version]} has been downloaded"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  warn R18n.t.fronde.tasks.org.downloaded(version: download.value)
         
     | 
| 
       35 
26 
     | 
    
         
             
                else
         
     | 
| 
       36 
     | 
    
         
            -
                  Fronde:: 
     | 
| 
      
 27 
     | 
    
         
            +
                  Fronde::CLI::Throbber.run(download, R18n.t.fronde.tasks.org.downloading)
         
     | 
| 
       37 
28 
     | 
    
         
             
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              rescue RuntimeError
         
     | 
| 
      
 30 
     | 
    
         
            +
                warn R18n.t.fronde.tasks.org.no_download if verbose
         
     | 
| 
       38 
31 
     | 
    
         
             
              end
         
     | 
| 
       39 
32 
     | 
    
         | 
| 
       40 
33 
     | 
    
         
             
              desc 'Compile Org'
         
     | 
| 
       41 
     | 
    
         
            -
               
     | 
| 
       42 
     | 
    
         
            -
                 
     | 
| 
      
 34 
     | 
    
         
            +
              multitask compile: ['var/tmp/org.tar.gz', 'lib'] do |task|
         
     | 
| 
      
 35 
     | 
    
         
            +
                begin
         
     | 
| 
      
 36 
     | 
    
         
            +
                  # No need to force fetch last version as it is only interesting as
         
     | 
| 
      
 37 
     | 
    
         
            +
                  # part of the upgrade task
         
     | 
| 
      
 38 
     | 
    
         
            +
                  org_version = Fronde::Org.last_version
         
     | 
| 
      
 39 
     | 
    
         
            +
                rescue RuntimeError
         
     | 
| 
      
 40 
     | 
    
         
            +
                  next
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
       43 
42 
     | 
    
         
             
                org_dir = "lib/org-#{org_version}"
         
     | 
| 
       44 
43 
     | 
    
         
             
                next if Dir.exist?("#{org_dir}/lisp")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       45 
45 
     | 
    
         
             
                build = Thread.new do
         
     | 
| 
       46 
     | 
    
         
            -
                   
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                   
     | 
| 
       49 
     | 
    
         
            -
                   
     | 
| 
       50 
     | 
    
         
            -
                  Dir.glob('lib/org-[0-9.]*').each do |ov|
         
     | 
| 
       51 
     | 
    
         
            -
                    next if ov == org_dir
         
     | 
| 
       52 
     | 
    
         
            -
                    rm_r ov
         
     | 
| 
       53 
     | 
    
         
            -
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  Fronde::Org.compile(
         
     | 
| 
      
 47 
     | 
    
         
            +
                    task.prerequisites[0], org_version, org_dir, verbose: verbose
         
     | 
| 
      
 48 
     | 
    
         
            +
                  )
         
     | 
| 
      
 49 
     | 
    
         
            +
                  Dir.glob('lib/org-[0-9.]*').each { rm_r _1 unless _1 == org_dir }
         
     | 
| 
       54 
50 
     | 
    
         
             
                end
         
     | 
| 
       55 
51 
     | 
    
         
             
                if verbose
         
     | 
| 
       56 
52 
     | 
    
         
             
                  build.join
         
     | 
| 
       57 
     | 
    
         
            -
                  warn  
     | 
| 
      
 53 
     | 
    
         
            +
                  warn R18n.t.fronde.tasks.org.installed(version: org_version)
         
     | 
| 
       58 
54 
     | 
    
         
             
                else
         
     | 
| 
       59 
     | 
    
         
            -
                  Fronde:: 
     | 
| 
      
 55 
     | 
    
         
            +
                  Fronde::CLI::Throbber.run(build, R18n.t.fronde.tasks.org.installing)
         
     | 
| 
       60 
56 
     | 
    
         
             
                end
         
     | 
| 
       61 
57 
     | 
    
         
             
              end
         
     | 
| 
       62 
58 
     | 
    
         | 
| 
         @@ -71,35 +67,59 @@ namespace :org do 
     | 
|
| 
       71 
67 
     | 
    
         | 
| 
       72 
68 
     | 
    
         
             
              file 'lib/ox-gmi.el' => 'lib' do
         
     | 
| 
       73 
69 
     | 
    
         
             
                ox_gmi = URI(
         
     | 
| 
       74 
     | 
    
         
            -
                  'https://git.umaneti.net/ox-gmi 
     | 
| 
      
 70 
     | 
    
         
            +
                  'https://git.umaneti.net/ox-gmi/plain/ox-gmi.el'
         
     | 
| 
       75 
71 
     | 
    
         
             
                ).open.read
         
     | 
| 
       76 
72 
     | 
    
         
             
                File.write 'lib/ox-gmi.el', ox_gmi
         
     | 
| 
       77 
73 
     | 
    
         
             
              end
         
     | 
| 
       78 
74 
     | 
    
         | 
| 
       79 
75 
     | 
    
         
             
              file 'var/lib/org-config.el' => ['lib/htmlize.el', 'lib/ox-gmi.el'] do
         
     | 
| 
       80 
     | 
    
         
            -
                Fronde:: 
     | 
| 
      
 76 
     | 
    
         
            +
                Fronde::CONFIG.write_org_lisp_config
         
     | 
| 
       81 
77 
     | 
    
         
             
              end
         
     | 
| 
       82 
78 
     | 
    
         | 
| 
       83 
79 
     | 
    
         
             
              file '.dir-locals.el' => 'var/lib/org-config.el' do
         
     | 
| 
       84 
     | 
    
         
            -
                Fronde::Config.write_dir_locals
         
     | 
| 
      
 80 
     | 
    
         
            +
                Fronde::Config::Helpers.write_dir_locals
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              file '.gitignore' do
         
     | 
| 
      
 84 
     | 
    
         
            +
                next if File.exist? '.gitignore'
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                upstream = File.expand_path(
         
     | 
| 
      
 87 
     | 
    
         
            +
                  '../fronde/cli/data/gitignore', __dir__
         
     | 
| 
      
 88 
     | 
    
         
            +
                )
         
     | 
| 
      
 89 
     | 
    
         
            +
                cp upstream, '.gitignore'
         
     | 
| 
       85 
90 
     | 
    
         
             
              end
         
     | 
| 
       86 
91 
     | 
    
         | 
| 
       87 
92 
     | 
    
         
             
              desc 'Install Org'
         
     | 
| 
       88 
     | 
    
         
            -
              multitask install: ['org:compile', '. 
     | 
| 
       89 
     | 
    
         
            -
                 
     | 
| 
       90 
     | 
    
         
            -
                 
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
      
 93 
     | 
    
         
            +
              multitask install: ['org:compile', '.gitignore'] do
         
     | 
| 
      
 94 
     | 
    
         
            +
                # I need a fully installed org mode to correctly generate the lisp
         
     | 
| 
      
 95 
     | 
    
         
            +
                # config
         
     | 
| 
      
 96 
     | 
    
         
            +
                Rake::Task['.dir-locals.el'].invoke
         
     | 
| 
      
 97 
     | 
    
         
            +
                sources = Fronde::CONFIG.sources
         
     | 
| 
      
 98 
     | 
    
         
            +
                sources.each { mkdir_p _1['path'] }
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                outputs = sources.map { _1['type'] }.uniq
         
     | 
| 
      
 101 
     | 
    
         
            +
                if outputs.include?('html')
         
     | 
| 
      
 102 
     | 
    
         
            +
                  mkdir_p "#{Fronde::CONFIG.get('html_public_folder')}/assets"
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
                if outputs.include?('gemini')
         
     | 
| 
      
 105 
     | 
    
         
            +
                  mkdir_p Fronde::CONFIG.get('gemini_public_folder')
         
     | 
| 
       92 
106 
     | 
    
         
             
                end
         
     | 
| 
       93 
107 
     | 
    
         
             
              end
         
     | 
| 
       94 
108 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
              # The following task only run the clobber task (not provided by us)
         
     | 
| 
       96 
     | 
    
         
            -
              # and the org:install one, which is already tested. Thus, we can
         
     | 
| 
       97 
     | 
    
         
            -
              # safely remove it from coverage.
         
     | 
| 
       98 
     | 
    
         
            -
              # :nocov:
         
     | 
| 
       99 
109 
     | 
    
         
             
              desc 'Upgrade Org'
         
     | 
| 
       100 
110 
     | 
    
         
             
              task :upgrade do
         
     | 
| 
       101 
111 
     | 
    
         
             
                Rake::Task['clobber'].execute
         
     | 
| 
      
 112 
     | 
    
         
            +
                if File.exist? 'var/tmp/org.tar.gz'
         
     | 
| 
      
 113 
     | 
    
         
            +
                  # Cleanup cached tarball only if a new version is available.
         
     | 
| 
      
 114 
     | 
    
         
            +
                  # Also cached the new remote org version in the same time.
         
     | 
| 
      
 115 
     | 
    
         
            +
                  org_version = Fronde::Org.current_version
         
     | 
| 
      
 116 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 117 
     | 
    
         
            +
                    last_version = Fronde::Org.last_version(force: true)
         
     | 
| 
      
 118 
     | 
    
         
            +
                  rescue RuntimeError
         
     | 
| 
      
 119 
     | 
    
         
            +
                    last_version = org_version
         
     | 
| 
      
 120 
     | 
    
         
            +
                  end
         
     | 
| 
      
 121 
     | 
    
         
            +
                  File.unlink 'var/tmp/org.tar.gz' unless org_version == last_version
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
       102 
123 
     | 
    
         
             
                Rake::Task['org:install'].invoke
         
     | 
| 
       103 
124 
     | 
    
         
             
              end
         
     | 
| 
       104 
     | 
    
         
            -
              # :nocov:
         
     | 
| 
       105 
125 
     | 
    
         
             
            end
         
     |