polites 0.1.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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +18 -0
  5. data/.tool-versions +1 -0
  6. data/.travis.yml +6 -0
  7. data/.yardopts +1 -0
  8. data/CODE_OF_CONDUCT.md +74 -0
  9. data/Gemfile +15 -0
  10. data/Gemfile.lock +128 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +70 -0
  13. data/Rakefile +9 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/exe/polites +8 -0
  17. data/lib/polites.rb +33 -0
  18. data/lib/polites/block.rb +65 -0
  19. data/lib/polites/block/blockquote.rb +8 -0
  20. data/lib/polites/block/code_block.rb +18 -0
  21. data/lib/polites/block/divider.rb +8 -0
  22. data/lib/polites/block/heading.rb +8 -0
  23. data/lib/polites/block/heading1.rb +8 -0
  24. data/lib/polites/block/heading2.rb +8 -0
  25. data/lib/polites/block/heading3.rb +8 -0
  26. data/lib/polites/block/heading4.rb +8 -0
  27. data/lib/polites/block/heading5.rb +8 -0
  28. data/lib/polites/block/heading6.rb +8 -0
  29. data/lib/polites/block/list.rb +14 -0
  30. data/lib/polites/block/ordered_list.rb +8 -0
  31. data/lib/polites/block/paragraph.rb +8 -0
  32. data/lib/polites/block/unordered_list.rb +8 -0
  33. data/lib/polites/cli.rb +52 -0
  34. data/lib/polites/convert.rb +29 -0
  35. data/lib/polites/doc/_index.html +85 -0
  36. data/lib/polites/doc/class_list.html +51 -0
  37. data/lib/polites/doc/css/common.css +1 -0
  38. data/lib/polites/doc/css/full_list.css +58 -0
  39. data/lib/polites/doc/css/style.css +496 -0
  40. data/lib/polites/doc/file_list.html +51 -0
  41. data/lib/polites/doc/frames.html +17 -0
  42. data/lib/polites/doc/index.html +85 -0
  43. data/lib/polites/doc/js/app.js +314 -0
  44. data/lib/polites/doc/js/full_list.js +216 -0
  45. data/lib/polites/doc/js/jquery.js +4 -0
  46. data/lib/polites/doc/method_list.html +51 -0
  47. data/lib/polites/doc/top-level-namespace.html +100 -0
  48. data/lib/polites/file.rb +67 -0
  49. data/lib/polites/html_formatter.rb +119 -0
  50. data/lib/polites/list_indenter.rb +34 -0
  51. data/lib/polites/markup.rb +31 -0
  52. data/lib/polites/nanoc.rb +46 -0
  53. data/lib/polites/nanoc/data_source.rb +93 -0
  54. data/lib/polites/nanoc/embedded_images_filter.rb +22 -0
  55. data/lib/polites/nanoc/extract_file_filter.rb +21 -0
  56. data/lib/polites/node.rb +28 -0
  57. data/lib/polites/parser.rb +174 -0
  58. data/lib/polites/plist.rb +28 -0
  59. data/lib/polites/range_tag.rb +29 -0
  60. data/lib/polites/settings.rb +35 -0
  61. data/lib/polites/sheet.rb +63 -0
  62. data/lib/polites/simple_tag.rb +22 -0
  63. data/lib/polites/span.rb +60 -0
  64. data/lib/polites/span/annotation.rb +18 -0
  65. data/lib/polites/span/code.rb +8 -0
  66. data/lib/polites/span/delete.rb +8 -0
  67. data/lib/polites/span/emph.rb +8 -0
  68. data/lib/polites/span/footnote.rb +18 -0
  69. data/lib/polites/span/image.rb +29 -0
  70. data/lib/polites/span/link.rb +21 -0
  71. data/lib/polites/span/mark.rb +8 -0
  72. data/lib/polites/span/strong.rb +8 -0
  73. data/lib/polites/tag.rb +20 -0
  74. data/lib/polites/text.rb +20 -0
  75. data/lib/polites/version.rb +5 -0
  76. data/polites-nanoc.gemspec +31 -0
  77. data/polites.gemspec +33 -0
  78. metadata +153 -0
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+ require 'json'
5
+
6
+ module Polites
7
+ # Read macos binary .plist files into a Hash by converting them to JSON format
8
+ # using the macos native `plutil` program. This only works on macos.
9
+ class Plist
10
+ # @param [#to_s] path
11
+ def initialize(path)
12
+ @path = path
13
+ end
14
+
15
+ # @return [Hash]
16
+ def to_h
17
+ @content ||= read_plist
18
+ end
19
+
20
+ private
21
+
22
+ def read_plist
23
+ "plutil -convert json -o - #{@path}"
24
+ .then { |s| Open3.capture2(s) }
25
+ .then { |(json, _)| JSON.parse(json) }
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './tag'
4
+
5
+ module Polites
6
+ # A range tag is a {Tag} defined by a start and an end pattern, such as used
7
+ # by defining bold formatting.
8
+ class RangeTag < Tag
9
+ # @return [String]
10
+ attr_reader :start_pattern
11
+ # @return [String]
12
+ attr_reader :end_pattern
13
+
14
+ # @param [String] name
15
+ # @param [String] start_pattern
16
+ # @param [String] end_pattern
17
+ def initialize(name, start_pattern, end_pattern)
18
+ super(name)
19
+ @start_pattern = start_pattern
20
+ @end_pattern = end_pattern
21
+ end
22
+
23
+ def eql?(other)
24
+ super &&
25
+ start_pattern == other.start_pattern &&
26
+ end_pattern == other.end_pattern
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './plist'
4
+
5
+ module Polites
6
+ # Settings is a wrapped around the combined configurations Polites writes to
7
+ # various Plist files in external directory.
8
+ class Settings
9
+ # Read all combined .plist files in a directory into a single data
10
+ # structure.
11
+ #
12
+ # @param [#to_s, #to_path] path root directory to look up .plist files in.
13
+ # @return [Polites::Settings]
14
+ def self.from_directory(path)
15
+ Pathname(path)
16
+ .glob('.*.plist')
17
+ .inject({}) { |s, f| s.merge Plist.new(f).to_h }
18
+ .then { |s| new(s) }
19
+ end
20
+
21
+ # @param [Hash] settings
22
+ def initialize(settings = {})
23
+ @settings = settings.to_h
24
+ freeze
25
+ end
26
+
27
+ # Look up a setting by key.
28
+ #
29
+ # @param [String] key
30
+ # @return [Object]
31
+ def [](key)
32
+ @settings[key]
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polites
4
+ # A sheet is represents a single "document" in Polites. It composes the main
5
+ # content in {Sheet#content}, its markup definition in {Sheet#markup}, any
6
+ # attaches files in {Sheet#files} and some metadata.
7
+ class Sheet
8
+ # @return [String]
9
+ attr_reader :version
10
+
11
+ # @return [String]
12
+ attr_reader :app_version
13
+
14
+ # @return [Markup]
15
+ attr_reader :markup
16
+
17
+ # @return [Array<Node>]
18
+ attr_reader :content
19
+
20
+ # @return [Array<String>]
21
+ attr_reader :keywords
22
+
23
+ # @return [Array<String>]
24
+ attr_reader :files
25
+
26
+ # @return [Array<Array<Node>>]
27
+ attr_reader :notes
28
+
29
+ # @param [String] version
30
+ # @param [String] app_version
31
+ # @param [Markup] markup
32
+ # @param [Array<Node>] content
33
+ # @param [Array<String>] keywords
34
+ # @param [Array<String>] files
35
+ # @param [Array<Array<Node>>] notes
36
+ def initialize(version:, app_version:, markup:, content:, keywords: [], files: [], notes: [])
37
+ @version = version
38
+ @app_version = app_version
39
+ @markup = markup
40
+ @content = content
41
+ @keywords = keywords
42
+ @files = files
43
+ @notes = notes
44
+ end
45
+
46
+ # Get all files that were referenced in the content, such as inline images.
47
+ #
48
+ # @return [Array<Span::Image>]
49
+ def inline_files
50
+ content.flat_map do |node|
51
+ node.children.grep(Span::Image)
52
+ end
53
+ end
54
+
55
+ # Get all files that were attached to the sheet without explicit mention in
56
+ # the content.
57
+ #
58
+ # @return [Array<String>]
59
+ def attached_files
60
+ files - inline_files.map(&:image)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './tag'
4
+
5
+ module Polites
6
+ # A simple tag is a {Tag} defined by a single pattern, such as for headings.
7
+ class SimpleTag < Tag
8
+ # @return [String]
9
+ attr_reader :pattern
10
+
11
+ # @param [String] name
12
+ # @param [String] pattern
13
+ def initialize(name, pattern)
14
+ super(name)
15
+ @pattern = pattern
16
+ end
17
+
18
+ def eql?(other)
19
+ super && pattern == other.pattern
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../polites'
4
+ require_relative './node'
5
+
6
+ module Polites
7
+ # A span is an element mapping to inline formatting, such as text formatting
8
+ # and images. Spans only exist within blocks and cannot themselves contain
9
+ # {Block} nodes.
10
+ class Span < Node
11
+ # Build the proper kind of span from the given arguments.
12
+ #
13
+ # @param [Array<Node>] children
14
+ # @param [String] kind the type Polites has given to this node.
15
+ # @param [String, nil] url the URL attribute for links.
16
+ # @param [String, nil] image the image fingerprint referring to a sheet file.
17
+ # @param [String, nil] filename the explicit filename to use for images.
18
+ # @param [String, nil] title the title attribute for links, images.
19
+ # @param [String, nil] description the description attribute used by images.
20
+ # @param [String, nil] width the explicitly configured image width
21
+ # @param [String, nil] height the explicitly configured image height
22
+ # @param [Array<Node>] text the contents of footnoes and annotation.
23
+ # @raise [ParseError] when encountering unexpected `kind`
24
+ # @return [Span]
25
+ def self.build(children = [], kind: nil, url: nil, image: nil, filename: nil, title: nil, description: nil, width: nil, height: nil, text: nil)
26
+ case kind
27
+ when 'link'
28
+ Span::Link.new(children, url: url, title: title)
29
+ when 'mark'
30
+ Span::Mark.new(children)
31
+ when 'emph'
32
+ Span::Emph.new(children)
33
+ when 'strong'
34
+ Span::Strong.new(children)
35
+ when 'annotation'
36
+ Span::Annotation.new(children, text)
37
+ when 'footnote'
38
+ Span::Footnote.new(children, text)
39
+ when 'delete'
40
+ Span::Delete.new(children)
41
+ when 'code'
42
+ Span::Code.new(children)
43
+ when 'image'
44
+ Span::Image.new(children, image: image, filename: filename, title: title, description: description, width: width, height: height)
45
+ else
46
+ raise ParseError, "unexpected kind #{kind.inspect}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ require_relative './span/link'
53
+ require_relative './span/emph'
54
+ require_relative './span/annotation'
55
+ require_relative './span/strong'
56
+ require_relative './span/footnote'
57
+ require_relative './span/image'
58
+ require_relative './span/mark'
59
+ require_relative './span/delete'
60
+ require_relative './span/code'
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Annotation < Span
7
+ attr_reader :text
8
+
9
+ def initialize(children, text)
10
+ super(children)
11
+ @text = text
12
+ end
13
+
14
+ def eql?(other)
15
+ super && text == other.text
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Code < Span
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Delete < Span
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Emph < Span
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Footnote < Span
7
+ attr_reader :text
8
+
9
+ def initialize(children, text)
10
+ super(children)
11
+ @text = text
12
+ end
13
+
14
+ def eql?(other)
15
+ super && text == other.text
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Image < Span
7
+ attr_reader :children, :image, :filename, :title, :description, :width, :height
8
+
9
+ def initialize(children, image:, filename: nil, title: nil, description: nil, width: nil, height: nil)
10
+ super(children)
11
+ @image = image
12
+ @filename = filename
13
+ @title = title
14
+ @description = description
15
+ @width = width
16
+ @height = height
17
+ end
18
+
19
+ def eql?(other)
20
+ super &&
21
+ image == other.image &&
22
+ filename == other.filename &&
23
+ title == other.title &&
24
+ description == other.description &&
25
+ width == other.width &&
26
+ height == other.height
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Link < Span
7
+ attr_reader :url, :title
8
+
9
+ def initialize(children = [], url:, title: nil)
10
+ super(children)
11
+ @url = url
12
+ @title = title
13
+ end
14
+
15
+ def eql?(other)
16
+ super &&
17
+ url == other.url &&
18
+ title == other.title
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Mark < Span
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../span'
4
+
5
+ module Polites
6
+ class Span::Strong < Span
7
+ end
8
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polites
4
+ # A tag is used to define the markup used in Polites documents.
5
+ class Tag
6
+ # @return [String]
7
+ attr_reader :name
8
+
9
+ # @param [String] name
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+
14
+ def eql?(other)
15
+ other.is_a?(self.class) && name == other.name
16
+ end
17
+
18
+ alias == eql?
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polites
4
+ # A piece of simple text to be output directly. A stand-in for a simple
5
+ # string.
6
+ class Text
7
+ attr_reader :text
8
+
9
+ # @param [String] text
10
+ def initialize(text)
11
+ @text = text
12
+ end
13
+
14
+ def eql?(other)
15
+ other.is_a?(self.class) && text == other.text
16
+ end
17
+
18
+ alias == eql?
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Polites
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/polites/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'polites-nanoc'
7
+ spec.version = Polites::VERSION
8
+ spec.authors = ['Arjan van der Gaag']
9
+ spec.email = ['arjan@arjanvandergaag.nl']
10
+
11
+ spec.summary = 'Integrate the Ulysess gem with Nanoc.'
12
+ spec.description = 'Use Polites\' .ulyz files as a data source in static sites generated with Nanoc.'
13
+ spec.homepage = 'https://github.com/avdgaag/polites'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+
19
+ spec.metadata['homepage_uri'] = spec.homepage
20
+ spec.metadata['source_code_uri'] = 'https://github.com/avdgaag/polites'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/avdgaag/polites'
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }.grep(/nanoc/)
27
+ end
28
+ spec.require_paths = ['lib']
29
+ spec.add_dependency 'nanoc', '~> 4'
30
+ spec.add_dependency 'polites', "~> #{Polites::VERSION}"
31
+ end