aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Étienne Deparis 2020-03-21 19:29:28 +0100
committerGravatar Étienne Deparis 2020-03-21 19:29:28 +0100
commitd9538120eaf1b7103d54b63120fcf37d7ec9c257 (patch)
tree8a45d25bdd4ade1d79a0c8c231ac1094bd6e2b29
parentb2d750c841dde99a8aa11ec712b7e3693532e3fe (diff)
parent156cfcab0b07ec7202e027f0244a2962a1df32f5 (diff)
downloadneruda-d9538120eaf1b7103d54b63120fcf37d7ec9c257.zip
neruda-d9538120eaf1b7103d54b63120fcf37d7ec9c257.tar.gz
neruda-d9538120eaf1b7103d54b63120fcf37d7ec9c257.tar.xz
Merge branch 'dev'v0.1.1
-rw-r--r--.gitignore7
-rw-r--r--.hgignore7
-rw-r--r--.rubocop.yml16
-rw-r--r--CONFIG.org101
-rw-r--r--Gemfile.lock52
-rw-r--r--README.org14
-rwxr-xr-xbin/pablo54
-rw-r--r--lib/neruda/index.rb7
-rw-r--r--lib/neruda/org_file.rb2
-rw-r--r--lib/neruda/utils.rb32
-rw-r--r--lib/neruda/version.rb2
-rw-r--r--neruda.gemspec2
-rw-r--r--spec/index_spec.rb4
-rw-r--r--spec/rake_site_spec.rb4
14 files changed, 237 insertions, 67 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..539f97f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+.byebug_history
+.ignore
+.ruby-gemset
+neruda-*.gem
+doc
+coverage
+.yardoc
diff --git a/.hgignore b/.hgignore
deleted file mode 100644
index 5b96d37..0000000
--- a/.hgignore
+++ /dev/null
@@ -1,7 +0,0 @@
-^.byebug_history$
-^.ignore$
-^.ruby-gemset$
-^neruda-.*\.gem$
-^doc
-^coverage
-^.yardoc
diff --git a/.rubocop.yml b/.rubocop.yml
index 2e89cbe..1b1e563 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -2,9 +2,20 @@
AllCops:
TargetRubyVersion: 2.5
+Layout:
+ Severity: warning
+
Layout/EmptyLineAfterGuardClause:
Enabled: false
+Layout/LineLength:
+ Max: 80
+ Exclude:
+ - spec/*
+
+Metrics:
+ Severity: warning
+
Metrics/AbcSize:
Enabled: false
@@ -15,11 +26,6 @@ Metrics/BlockLength:
- lib/tasks/*
- neruda.gemspec
-Metrics/LineLength:
- Max: 80
- Exclude:
- - spec/*
-
Metrics/MethodLength:
Max: 15
diff --git a/CONFIG.org b/CONFIG.org
new file mode 100644
index 0000000..6730462
--- /dev/null
+++ b/CONFIG.org
@@ -0,0 +1,101 @@
+#+title: Neruda config.yml file
+#+author: Étienne Deparis
+#+lang: en
+#+description: Glossary of all possible configuration options for Neruda
+
+This file explain all possible configuration options for Neruda, which
+may be put in file named ~config.yml~ at the root of your static website
+project. The options are listed in alphabetical order. However, they can
+be put in any order in the ~config.yml~ file.
+
+* ~author~
+
+The ~author~ option stores the default author name of your org
+files. This value is used when you create a new file. *It is not used by
+the regular org mode publishing process*. You must be sure that your org
+files contains an ~#+author:~ metadata field before publishing them.
+
+This value is used in the generation of the blog index page and the main
+atom feed.
+
+* <<sec:blog_path>> ~blog_path~
+
+The ~blog_path~ options store the folder name *inside* the ~src~ folder,
+which will contains org document to be specifically indexed to produce a
+blog-like website.
+
+Neruda will introspect the org documents inside this folder in order to
+find keywords (declared with the ~#+keywords:~ header) and produce as
+many new time-sorted indexes for these keywords, plus a specific index
+page at the root of this folder.
+
+The default value is ~blog~.
+
+* <<sec:blog_pattern>> ~blog_pattern~
+
+The ~blog_pattern~ option stores a [[https://en.wikipedia.org/wiki/Glob_(programming)][glob pattern]] to help Neruda to find
+the documents you want to index under the [[sec:blog_path][~blog_path~]] folder. It may be
+handy to only selecte precisely some files. The default value is
+~**/*.org~, which means absolutely all org documents (under the
+~blog_path~).
+
+See also the [[sec:exclude_pattern][~exclude_pattern~ section]].
+
+* ~domain~
+
+The domain name pointing to where your static website is expected to be
+hosted. This value is used to generate absolute path to your files on
+your expected host name (for example in the Atom feeds). Its value is
+expected to *not* end by a slash. That is to say ~https://example.com~
+is a *valid* value, while ~https://example.com/~ is not. Its default
+value is an empty string.
+
+By default, your static website is expected to be hosted at the root of
+your domain name (like ~https://example.com/index.html~). If it is not
+the case and your neruda static website is hosted in a sub directory of
+your main website, you must add this sub folder to the ~domain~
+value. Thus, ~https://example.com/example~ or
+~https://example.com/complex/example~ are *valid* values too, while
+~https://example.com/example/~ or ~https://example.com/complex/example/~
+are not.
+
+* <<sec:exclude_pattern>> ~exclude_pattern~
+
+The ~exclude_pattern~ option stores a [[https://en.wikipedia.org/wiki/Regular_expression][regular expression]] to help Neruda
+to find precisely which files you want to index under the [[sec:blog_path][~blog_path~]]
+folder. It may be handy to remove some unrelated data files, for example
+with a value like ~comments\.org$~. This filter is executed *after*
+files have been selected by the [[sec:blog_pattern][~blog_pattern~]] and *matching* files are
+excluded.
+
+There is no default value (thus nothing match and thus all org files
+matched by the ~blog_pattern~ option are indexed).
+
+See also the [[sec:blog_pattern][~blog_pattern~ section]].
+
+* ~lang~
+
+The main locale your website will be written in. Its value must comply
+with the [[https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes][ISO 639-1]] standard.
+
+* ~public_folder~
+
+The ~public_folder~ option stores the path to the folder, which will
+contains the generated files, ready for publication. It's default value
+is ~public_html~ (at the root of your project).
+
+* ~remote~
+
+The ~remote~ option contains an /rsync/ like destination string, which
+will be used to published your website when using the ~sync:push~ /rake/
+task. For exemple ~user@domain:/var/www/mywebsite/~
+
+* ~title~
+
+The ~title~ option stores the default title of your org files. This value
+is used when you create a new file. *It is not used by the regular org
+mode publishing process*. You must be sure that your org files contains
+an ~#+title:~ metadata field before publishing them.
+
+This value is used in the generation of the blog index page and the main
+atom feed.
diff --git a/Gemfile.lock b/Gemfile.lock
index 9a7f953..64fd8f0 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -2,20 +2,20 @@ GEM
remote: https://rubygems.org/
specs:
ast (2.4.0)
- byebug (11.0.1)
+ byebug (11.1.0)
coderay (1.1.2)
diff-lcs (1.3)
docile (1.3.2)
- jaro_winkler (1.5.2)
- json (2.2.0)
+ jaro_winkler (1.5.4)
+ json (2.3.0)
method_source (0.9.2)
mini_portile2 (2.4.0)
- nokogiri (1.10.3)
+ nokogiri (1.10.7)
mini_portile2 (~> 2.4.0)
org-ruby (0.9.12)
rubypants (~> 0.2)
- parallel (1.17.0)
- parser (2.6.3.0)
+ parallel (1.19.1)
+ parser (2.7.0.2)
ast (~> 2.4.0)
pry (0.12.2)
coderay (~> 1.1.0)
@@ -25,36 +25,36 @@ GEM
yard (~> 0.9.11)
r18n-core (3.2.0)
rainbow (3.0.0)
- rake (12.3.2)
- rspec (3.8.0)
- rspec-core (~> 3.8.0)
- rspec-expectations (~> 3.8.0)
- rspec-mocks (~> 3.8.0)
- rspec-core (3.8.0)
- rspec-support (~> 3.8.0)
- rspec-expectations (3.8.4)
+ rake (12.3.3)
+ rspec (3.9.0)
+ rspec-core (~> 3.9.0)
+ rspec-expectations (~> 3.9.0)
+ rspec-mocks (~> 3.9.0)
+ rspec-core (3.9.1)
+ rspec-support (~> 3.9.1)
+ rspec-expectations (3.9.0)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-mocks (3.8.0)
+ rspec-support (~> 3.9.0)
+ rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.8.0)
- rspec-support (3.8.2)
- rubocop (0.70.0)
+ rspec-support (~> 3.9.0)
+ rspec-support (3.9.2)
+ rubocop (0.79.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
- parser (>= 2.6)
+ parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
- ruby-progressbar (1.10.0)
- rubypants (0.7.0)
- simplecov (0.16.1)
+ ruby-progressbar (1.10.1)
+ rubypants (0.7.1)
+ simplecov (0.17.1)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
- unicode-display_width (1.6.0)
- yard (0.9.19)
+ unicode-display_width (1.6.1)
+ yard (0.9.24)
PLATFORMS
ruby
@@ -77,4 +77,4 @@ RUBY VERSION
ruby 2.6.3p62
BUNDLED WITH
- 2.0.1
+ 2.1.4
diff --git a/README.org b/README.org
index ce347c0..8b68d6b 100644
--- a/README.org
+++ b/README.org
@@ -7,11 +7,12 @@
* What's for?
+#+attr_html: :style width:150px;float:right;margin-top:-4.5em;margin-left:2em;
+[[file:themes/default/assets/Firma_Pablo_Neruda.svg]]
+
Neruda is a static website generator made for [[https://orgmode.org][org files]]. It improves the
default org mode HTML exporting/publishing routine.
-See [[https://deparis.io/neruda/][the official website]] for more information.
-
* Features
- Inherit all [[https://orgmode.org][org mode features]] (tables, syntax highlighting,
@@ -40,3 +41,12 @@ Now, you're ready to create your first Neruda website.
#+begin_src shell
pablo init -t "My first neruda website"
#+end_src
+
+* Going further
+
+All the Neruda configuration is stored in one [[https://en.wikipedia.org/wiki/YAML][YAML]] file named
+~config.yml~ and stored at the root of your project. If none exists, a
+default one will be created the first time you run any ~pablo~ command.
+
+You should read the [[./CONFIG.org][config file documentation]] to discover its various
+options.
diff --git a/bin/pablo b/bin/pablo
index a063d72..3f5bc3e 100755
--- a/bin/pablo
+++ b/bin/pablo
@@ -35,38 +35,55 @@ module PabloCommands
end
def pablo_preview
+ Thread.new do
+ sleep 1
+ port = Neruda::Config.settings['server_port'] || 5000
+ uri = "http://127.0.0.1:#{port}/"
+ current_os = Neruda::Utils.current_os
+ if current_os == 'windows'
+ system 'start', uri
+ elsif current_os == 'apple'
+ system 'open', uri
+ else
+ system 'gio', 'open', uri
+ end
+ end
@rake.invoke_task('site:preview')
end
def pablo_open
- filename = ARGV[0] || new_file_name
+ filename = new_file_name(ARGV[0])
FileUtils.mkdir_p File.dirname(filename)
o = Neruda::OrgFile.new(filename, @options)
o.write unless File.exist? filename
-
editor = ENV['EDITOR'] || ENV['VISUAL'] || 'emacs'
cmd = [editor, filename]
cmd.insert(1, '+6') if editor.match?(/^emacs/)
system(*cmd)
end
+ alias_method :pablo_edit, :pablo_open
+
+ def pablo_publish
+ @rake.invoke_task('sync:push')
+ end
def pablo_help(command = 'basic', error = false)
warn R18n.t.pablo.error.no_command if error
- command = 'basic' unless Neruda::Utils::PABLO_COMMANDS.include?(command)
- cmd_opt = Neruda::Utils::PABLO_COMMANDS[command]
+ cmd = Neruda::Utils.resolve_possible_alias(command)
+ cmd_opt = Neruda::Utils::PABLO_COMMANDS[cmd]
label = cmd_opt[:label] || command
warn "Usage: pablo #{label} [options]\n\n"
warn cmd_opt[:desc] + "\n\n" if cmd_opt.has_key?(:desc)
- warn "Options\n#{Neruda::Utils.summarize_command(command)}\n"
- warn "Commands\n#{Neruda::Utils.list_commands}\n" if command == 'basic'
+ warn "Options\n#{Neruda::Utils.summarize_command(cmd)}\n"
+ warn "Commands\n#{Neruda::Utils.list_commands}\n" if cmd == 'basic'
exit 1 if error
exit
end
private
- def new_file_name
- title = @options[:title]
+ def new_file_name(title)
+ title ||= @options[:title]
title = 'new' if title.nil? || title == ''
filename = Neruda::OrgFile.slug title
return "#{filename}.org" unless @options[:directory]
@@ -112,14 +129,14 @@ class Pablo
end
end
-params = {}
-optparser = OptionParser.new do |opts|
- opts.version = Neruda::VERSION
- Neruda::Utils::PABLO_OPTIONS.each do |k, opt|
- short, long = Neruda::Utils.decorate_option(k)
- opts.send(opt[:meth] || :on, short, long, opt[:desc])
- end
+optparser = OptionParser.new
+optparser.version = Neruda::VERSION
+
+Neruda::Utils::PABLO_OPTIONS.each do |k, opt|
+ optparser.send(opt[:meth] || :on, *Neruda::Utils.decorate_option(k))
end
+
+params = {}
optparser.parse!(into: params)
if params[:version]
@@ -133,8 +150,11 @@ if ARGV[0] == 'help'
end
pablo = Pablo.new(params)
command = "pablo_#{ARGV[0]}".to_sym
-err = command.nil? || !pablo.respond_to?(command)
-pablo.pablo_help(ARGV[0], err) if err || params[:help]
+cmd_err = !pablo.respond_to?(command)
+if params[:help] || cmd_err
+ cmd_err = false if params[:help] && !ARGV[0]
+ pablo.pablo_help(ARGV[0], cmd_err)
+end
ARGV.shift
init_cmds = ['pablo_init', 'pablo_config']
diff --git a/lib/neruda/index.rb b/lib/neruda/index.rb
index dc5bdf2..1821073 100644
--- a/lib/neruda/index.rb
+++ b/lib/neruda/index.rb
@@ -49,7 +49,12 @@ module Neruda
def sort_by(kind)
if [:name, :weight].include?(kind)
- return sort_tags_by_name_and_weight["by_#{kind}".to_sym]
+ tags_sorted = sort_tags_by_name_and_weight["by_#{kind}".to_sym]
+ # Reverse in order to have most important or A near next prompt
+ # and avoid to scroll to find the beginning of the list.
+ return tags_sorted.map do |k|
+ @tags_names[k] + " (#{@index[k].length})"
+ end.reverse
end
raise ArgumentError, "#{kind} not in [:name, :weight]"
end
diff --git a/lib/neruda/org_file.rb b/lib/neruda/org_file.rb
index 65d2500..9149f67 100644
--- a/lib/neruda/org_file.rb
+++ b/lib/neruda/org_file.rb
@@ -252,7 +252,7 @@ module Neruda
@notime = false
@author = @options[:author] || Neruda::Config.settings['author']
@keywords = []
- @lang = Neruda::Config.settings['lang']
+ @lang = @options[:lang] || Neruda::Config.settings['lang']
@excerpt = ''
@content = @options[:content] || <<~ORG
#+title: #{@title}
diff --git a/lib/neruda/utils.rb b/lib/neruda/utils.rb
index 4c4a9d5..b68bfd5 100644
--- a/lib/neruda/utils.rb
+++ b/lib/neruda/utils.rb
@@ -41,11 +41,16 @@ module Neruda
'init' => { opts: ['-a', '-l', '-t', '-v', '-h'],
desc: 'Initialize your Neruda instance ' \
'(you just need to do it once).' },
+ 'config' => { alias: 'init' },
'preview' => { opts: ['-h'],
desc: 'Start a test webserver to preview ' \
'your website on http://127.0.0.1:5000' },
'open' => { opts: ['-a', '-l', '-t', '-d', '-p', '-v', '-h'],
desc: 'Open or create an org file for edition.' },
+ 'edit' => { alias: 'open' },
+ 'publish' => { opts: ['-h'],
+ desc: 'Push local changes to your public ' \
+ 'server online.' },
'help' => { opts: ['-h'], desc: 'Alias for the -h switch.' },
'basic' => { opts: ['-h', '-V'], label: '<command>' }
}.freeze
@@ -95,8 +100,8 @@ module Neruda
opt = Neruda::Utils::PABLO_OPTIONS[short]
long = "--#{opt[:long]}"
return [short, long] if opt[:boolean]
- key = ' ' + (opt[:keyword] || opt[:long].upcase)
- [short + key, long + key]
+ key = opt[:keyword] || opt[:long].upcase
+ [short + key, long + ' ' + key]
end
# Returns the ~pablo~ help summary for a given command.
@@ -125,6 +130,29 @@ module Neruda
end
lines
end
+
+ # Returns the real command name for a given command, which may be
+ # an alias.
+ #
+ # @param command [String] the command to resolve
+ # @return [String]
+ def resolve_possible_alias(command)
+ return 'basic' unless Neruda::Utils::PABLO_COMMANDS.include?(command)
+ cmd_opt = Neruda::Utils::PABLO_COMMANDS[command]
+ return cmd_opt[:alias] if cmd_opt.has_key?(:alias)
+ command
+ end
+
+ # Try to discover the current host operating system.
+ #
+ # @return [String] either apple, windows or linux (default)
+ def current_os
+ if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM =~ /cygwin/
+ return 'windows'
+ end
+ return 'apple' if RUBY_PLATFORM =~ /darwin/
+ 'linux'
+ end
end
end
end
diff --git a/lib/neruda/version.rb b/lib/neruda/version.rb
index 3d9a8e3..c528e67 100644
--- a/lib/neruda/version.rb
+++ b/lib/neruda/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Neruda
- VERSION = '0.1.0'
+ VERSION = '0.1.1'
end
diff --git a/neruda.gemspec b/neruda.gemspec
index 82728ac..5252108 100644
--- a/neruda.gemspec
+++ b/neruda.gemspec
@@ -41,7 +41,7 @@ Gem::Specification.new do |s|
# Others
'LICENSE']
s.executables = ['pablo']
- s.homepage = 'https://hg.deparis.io/neruda/'
+ s.homepage = 'https://git.deparis.io/neruda/'
s.license = 'WTFPL'
s.rdoc_options << '-m' << 'org'
diff --git a/spec/index_spec.rb b/spec/index_spec.rb
index f68b15a..d30257e 100644
--- a/spec/index_spec.rb
+++ b/spec/index_spec.rb
@@ -137,12 +137,12 @@ describe 'With blog settings' do
it 'should list tags by name', core: true do
list = @index.sort_by :name
- expect(list).to eql(['toto', 'tutu'])
+ expect(list).to eql(['tutu (2)', 'toto (1)'])
end
it 'should list tags by weight', core: true do
list = @index.sort_by :weight
- expect(list).to eql(['tutu', 'toto'])
+ expect(list).to eql(['toto (1)', 'tutu (2)'])
end
it 'should raise an error if sort_by is called with bad argument', core: true do
diff --git a/spec/rake_site_spec.rb b/spec/rake_site_spec.rb
index 8a2dbcb..867cfcd 100644
--- a/spec/rake_site_spec.rb
+++ b/spec/rake_site_spec.rb
@@ -159,11 +159,11 @@ describe 'With a testing website' do
end
it 'should list all tags by name', rake: true do
- expect { @rake.invoke_task('tags:name') }.to output("titi\ntoto\n").to_stdout
+ expect { @rake.invoke_task('tags:name') }.to output("toto (2)\ntiti (1)\n").to_stdout
end
it 'should list all tags by weight', rake: true do
- expect { @rake.invoke_task('tags:weight') }.to output("toto\ntiti\n").to_stdout
+ expect { @rake.invoke_task('tags:weight') }.to output("titi (1)\ntoto (2)\n").to_stdout
end
end