rawfeed 0.3.1 → 1.0.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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +25 -0
  3. data/.gitignore +19 -0
  4. data/.gitlab/ci/gitlab-pages.yml +51 -0
  5. data/.hidden +6 -0
  6. data/404.html +6 -0
  7. data/Gemfile +51 -0
  8. data/README.md +102 -26
  9. data/_config.yml +77 -0
  10. data/_data/generic.yml +29 -0
  11. data/_data/screen/blog.yml +46 -0
  12. data/_data/screen/contact.yml +31 -0
  13. data/_data/screen/donate.yml +45 -0
  14. data/_data/screen/footer.yml +17 -0
  15. data/_data/screen/head.yml +49 -0
  16. data/_data/screen/home.yml +24 -0
  17. data/_data/screen/maintenance.yml +8 -0
  18. data/_data/screen/navbar.yml +41 -0
  19. data/_data/screen/page.yml +12 -0
  20. data/_data/screen/pixels.yml +7 -0
  21. data/_data/screen/pub.yml +4 -0
  22. data/_data/{resume.yml → screen/resume.yml} +8 -8
  23. data/_data/screen/socials.yml +20 -0
  24. data/_includes/assigned +36 -0
  25. data/_includes/layout/blog_search.html +22 -15
  26. data/_includes/layout/disqus.html +7 -8
  27. data/_includes/layout/footer.html +43 -28
  28. data/_includes/layout/giscus.html +15 -19
  29. data/_includes/layout/head.html +97 -75
  30. data/_includes/layout/maintenance.html +14 -11
  31. data/_includes/layout/navbar.html +253 -0
  32. data/_includes/layout/paginator.html +12 -13
  33. data/_includes/{alert → markdown/alert} +2 -2
  34. data/_includes/{chart → markdown/chart} +3 -3
  35. data/_includes/{image → markdown/image} +4 -4
  36. data/_includes/{socials → markdown/socials} +5 -5
  37. data/_includes/{video → markdown/video} +2 -2
  38. data/_layouts/blog/index.html +53 -0
  39. data/_layouts/{post.html → blog/post.html} +50 -36
  40. data/_layouts/blog/posts_by_tag.html +27 -0
  41. data/_layouts/blog/tags.html +32 -0
  42. data/_layouts/contact.html +156 -114
  43. data/_layouts/default.html +53 -48
  44. data/_layouts/donate.html +112 -0
  45. data/_layouts/error.html +9 -7
  46. data/_layouts/home.html +22 -19
  47. data/_layouts/licenses.html +2 -2
  48. data/_layouts/page.html +18 -17
  49. data/_layouts/pixels/index.html +75 -0
  50. data/_layouts/{pixel.html → pixels/post.html} +5 -5
  51. data/_layouts/pub.html +50 -44
  52. data/_layouts/resume.html +308 -265
  53. data/_pages/any-page.md +336 -0
  54. data/_pages/contact.md +16 -0
  55. data/_pages/donate.md +16 -0
  56. data/_pages/licenses.md +17 -0
  57. data/_pages/resume.md +14 -0
  58. data/_pixels/2025-10-15-first-my-pixel.md +34 -0
  59. data/_posts/2025-09-20-welcome-to-jekyll.md +36 -0
  60. data/_posts/2025-09-25-this-post-demonstrates-post-codeblocks.md +141 -0
  61. data/_posts/2025-09-25-this-post-demonstrates-post-content-styles.md +133 -0
  62. data/_posts/2025-10-04-content-styles-and-codeblocks.md +330 -0
  63. data/_sass/components/_markdown.scss +2 -2
  64. data/_sass/includes/_index.scss +2 -2
  65. data/_sass/includes/{_header.scss → _navbar.scss} +2 -6
  66. data/_sass/includes/_toc.scss +146 -0
  67. data/_sass/layouts/_blog.scss +1 -1
  68. data/_sass/layouts/_index.scss +2 -2
  69. data/_sass/layouts/_page.scss +0 -5
  70. data/_sass/layouts/_post.scss +8 -138
  71. data/_sass/layouts/{_tag-posts.scss → _posts_by_tag.scss} +3 -3
  72. data/_sass/layouts/_resume.scss +1 -1
  73. data/_sass/layouts/{_tag.scss → _tags.scss} +10 -6
  74. data/_sass/main.scss +2 -2
  75. data/_sass/theme/_dark.scss +2 -2
  76. data/_sass/theme/_light.scss +1 -1
  77. data/assets/js/blog.js +52 -18
  78. data/assets/js/contact.js +21 -20
  79. data/assets/js/default.js +67 -50
  80. data/assets/js/discus.js +2 -2
  81. data/assets/js/{donation.js → donate.js} +10 -9
  82. data/assets/js/home.js +18 -16
  83. data/assets/js/page.js +50 -172
  84. data/assets/js/toc.js +133 -0
  85. data/assets/json/blog_search.json +5 -7
  86. data/assets/vendors/fuse.min.js +9 -0
  87. data/blog/index.md +14 -0
  88. data/blog/tags/index.md +12 -0
  89. data/exe/rawfeed +29 -0
  90. data/index.md +15 -0
  91. data/lib/rawfeed/build/cleaner.rb +60 -0
  92. data/lib/rawfeed/build/image_minifier.rb +163 -0
  93. data/lib/rawfeed/build/minifier.rb +89 -0
  94. data/lib/rawfeed/build.rb +9 -0
  95. data/lib/rawfeed/command/backup.rb +124 -0
  96. data/lib/rawfeed/command/cli.rb +118 -0
  97. data/lib/rawfeed/command/installer.rb +156 -0
  98. data/lib/rawfeed/command/tools.rb +138 -0
  99. data/lib/rawfeed/{author.rb → content/author.rb} +7 -7
  100. data/lib/rawfeed/content/contact.rb +51 -0
  101. data/lib/rawfeed/content/donate.rb +48 -0
  102. data/lib/rawfeed/{draft.rb → content/draft.rb} +5 -3
  103. data/lib/rawfeed/content/licenses.rb +46 -0
  104. data/lib/rawfeed/{page.rb → content/page.rb} +4 -3
  105. data/lib/rawfeed/{pixel.rb → content/pixel.rb} +7 -4
  106. data/lib/rawfeed/content/post.rb +107 -0
  107. data/lib/rawfeed/{resume.rb → content/resume.rb} +23 -19
  108. data/lib/rawfeed/{layout.rb → core/layout.rb} +1 -1
  109. data/lib/rawfeed/core/utils.rb +103 -0
  110. data/lib/rawfeed/{version.rb → core/version.rb} +1 -1
  111. data/lib/rawfeed/{datelang.rb → plugin/datelang.rb} +5 -6
  112. data/lib/rawfeed/{pub.rb → plugin/pub.rb} +33 -31
  113. data/lib/rawfeed/{reading_time.rb → plugin/reading_time.rb} +5 -4
  114. data/lib/rawfeed/root.rb +3 -0
  115. data/lib/rawfeed.rb +36 -14
  116. data/pixels/index.md +11 -0
  117. data/robots.txt +26 -0
  118. metadata +153 -195
  119. data/_data/options.yml +0 -329
  120. data/_includes/layout/data.liquid +0 -31
  121. data/_includes/layout/header.html +0 -173
  122. data/_layouts/blog.html +0 -52
  123. data/_layouts/donation.html +0 -113
  124. data/_layouts/pixels.html +0 -71
  125. data/_layouts/tag.html +0 -33
  126. data/_layouts/tag_posts.html +0 -28
  127. data/assets/vendor/simple-jekyll-search.js +0 -433
  128. data/assets/vendor/simple-jekyll-search.min.js +0 -6
  129. data/lib/rawfeed/installer.rb +0 -37
  130. data/lib/rawfeed/post.rb +0 -60
  131. data/lib/rawfeed/utils.rb +0 -75
  132. /data/_includes/{details → markdown/details} +0 -0
  133. /data/_includes/{enddetails → markdown/enddetails} +0 -0
  134. /data/_includes/{endtabs → markdown/endtabs} +0 -0
  135. /data/_includes/{tabs → markdown/tabs} +0 -0
  136. /data/assets/images/{avatar_back.png → avatars/back.png} +0 -0
  137. /data/assets/images/{avatar_dark.png → avatars/dark.png} +0 -0
  138. /data/assets/images/{avatar_light.png → avatars/light.png} +0 -0
  139. /data/assets/images/{icons → donate}/bitcoin.svg +0 -0
  140. /data/assets/images/{icons → donate}/card.svg +0 -0
  141. /data/assets/images/{icons → donate}/donation.svg +0 -0
  142. /data/assets/images/{icons → donate}/lightning_network.svg +0 -0
  143. /data/assets/images/{icons → donate}/paypal.svg +0 -0
  144. /data/assets/images/{icons → donate}/pix.svg +0 -0
  145. /data/assets/images/{qrcode_btc_binance.jpg → donate/qrcode_btc_binance.jpg} +0 -0
  146. /data/assets/images/{qrcode_inter.jpg → donate/qrcode_inter.jpg} +0 -0
  147. /data/assets/images/{qrcode_wos.jpg → donate/qrcode_wos.jpg} +0 -0
  148. /data/assets/images/{icons → donate}/wos.png +0 -0
  149. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.css +0 -0
  150. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.css.map +0 -0
  151. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.min.css +0 -0
  152. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.min.css.map +0 -0
  153. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.rtl.css +0 -0
  154. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.rtl.css.map +0 -0
  155. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.rtl.min.css +0 -0
  156. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-grid.rtl.min.css.map +0 -0
  157. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.css +0 -0
  158. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.css.map +0 -0
  159. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.min.css +0 -0
  160. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.min.css.map +0 -0
  161. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.rtl.css +0 -0
  162. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.rtl.css.map +0 -0
  163. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.rtl.min.css +0 -0
  164. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-reboot.rtl.min.css.map +0 -0
  165. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.css +0 -0
  166. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.css.map +0 -0
  167. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.min.css +0 -0
  168. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.min.css.map +0 -0
  169. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.rtl.css +0 -0
  170. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.rtl.css.map +0 -0
  171. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.rtl.min.css +0 -0
  172. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap-utilities.rtl.min.css.map +0 -0
  173. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.css +0 -0
  174. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.css.map +0 -0
  175. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.min.css +0 -0
  176. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.min.css.map +0 -0
  177. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.rtl.css +0 -0
  178. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.rtl.css.map +0 -0
  179. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.rtl.min.css +0 -0
  180. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/css/bootstrap.rtl.min.css.map +0 -0
  181. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.bundle.js +0 -0
  182. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.bundle.js.map +0 -0
  183. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.bundle.min.js +0 -0
  184. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.bundle.min.js.map +0 -0
  185. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.esm.js +0 -0
  186. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.esm.js.map +0 -0
  187. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.esm.min.js +0 -0
  188. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.esm.min.js.map +0 -0
  189. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.js +0 -0
  190. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.js.map +0 -0
  191. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.min.js +0 -0
  192. /data/assets/{vendor/bootstrap → vendors/bootstrap-5.2.3}/js/bootstrap.min.js.map +0 -0
  193. /data/lib/rawfeed/{csp_filters.rb → plugin/csp_filters.rb} +0 -0
  194. /data/lib/rawfeed/{typescript_liquid.rb → plugin/typescript_liquid.rb} +0 -0
  195. /data/lib/rawfeed/{with_class.rb → plugin/with_class.rb} +0 -0
@@ -0,0 +1,156 @@
1
+ require "rawfeed/root"
2
+
3
+ module Rawfeed
4
+ class Installer
5
+ def self.gem_root
6
+ if defined?(Gem) && Gem.loaded_specs["rawfeed"]
7
+ Gem.loaded_specs["rawfeed"].full_gem_path
8
+ else
9
+ Rawfeed::ROOT
10
+ end
11
+ end
12
+
13
+ # Generic function to copy files or folders
14
+ # If dest is a nested directory, it automatically creates the parent directories
15
+ def self.copy_items(items, dest_path, force = false)
16
+ items.each do |src, dest_rel|
17
+ dest = File.join(dest_path, dest_rel)
18
+
19
+ # Creates parent directory if it doesn't exist.
20
+ FileUtils.mkdir_p(File.dirname(dest))
21
+
22
+ if File.exist?(src) || Dir.exist?(src)
23
+ # Remove destination if it already exists and force is true
24
+ if force && (File.exist?(dest) || Dir.exist?(dest))
25
+ if Dir.exist?(dest)
26
+ FileUtils.rm_rf(dest)
27
+ else
28
+ File.delete(dest)
29
+ end
30
+ end
31
+
32
+ FileUtils.cp_r(src, dest)
33
+ else
34
+ puts "Warning: #{src} not found".yellow
35
+ end
36
+ end
37
+ end
38
+
39
+ def self.create_new_site(path, *args)
40
+ force = args.include?("--force")
41
+
42
+ # Normalize path
43
+ path = "." if path.nil? || path.empty?
44
+ actual_path = File.expand_path(path)
45
+
46
+ # Check if directory exists and is not empty
47
+ if Dir.exist?(actual_path)
48
+ entries = Dir.entries(actual_path) - [".", ".."]
49
+
50
+ if entries.any?
51
+ unless force
52
+ puts "Directory #{path} is not empty!".red
53
+ puts "Use the --force flag to proceed: rawfeed new #{path} --force".yellow
54
+ return
55
+ end
56
+ end
57
+ else
58
+ FileUtils.mkdir_p(actual_path)
59
+ end
60
+
61
+ gem_dir = gem_root
62
+
63
+ # --- files and folders to copy ---
64
+ items_to_copy = [
65
+ [File.join(gem_dir, "Gemfile"), "Gemfile"],
66
+ [File.join(gem_dir, "_config.yml"), "_config.yml"],
67
+ [File.join(gem_dir, "index.md"), "index.md"],
68
+ [File.join(gem_dir, "404.html"), "404.html"],
69
+ [File.join(gem_dir, ".gitignore"), ".gitignore"],
70
+ [File.join(gem_dir, ".gitlab/ci/gitlab-pages.yml"), ".gitlab/ci/gitlab-pages.yml"],
71
+ [File.join(gem_dir, ".github/workflows/github-pages.yml"), ".github/workflows/github-pages.yml"],
72
+ [File.join(gem_dir, ".editorconfig"), ".editorconfig"],
73
+ [File.join(gem_dir, ".hidden"), ".hidden"],
74
+ [File.join(gem_dir, "robots.txt"), "robots.txt"],
75
+
76
+ [File.join(gem_dir, "_data"), "_data"],
77
+ [File.join(gem_dir, "_posts"), "_posts"],
78
+ [File.join(gem_dir, "_pages"), "_pages"],
79
+ [File.join(gem_dir, "_pixels"), "_pixels"],
80
+ [File.join(gem_dir, "blog"), "blog"],
81
+ [File.join(gem_dir, "pixels"), "pixels"],
82
+ [File.join(gem_dir, "assets/images"), "assets/images"]
83
+ ]
84
+
85
+ copy_items(items_to_copy, actual_path, force)
86
+
87
+ # --- Bundle config set ---
88
+ puts <<~MSG.yellow.bold
89
+ To silence rubyzip post-install messages, run:
90
+
91
+ bundle config set --local ignore_messages true
92
+ MSG
93
+
94
+ # --- Gemfile --- DEPRECATED - Using the dev's Gemfile
95
+ # gemfile_dest = File.join(actual_path, "Gemfile")
96
+ # create_gemfile(actual_path) unless File.exist?(gemfile_dest)
97
+
98
+ # --- final ---
99
+ puts "New rawfeed site created at #{path}".green
100
+ end
101
+
102
+ # DEPRECATED - Using the dev's Gemfile
103
+ # def self.create_gemfile(path)
104
+ # content = <<~GEMFILE
105
+ # # frozen_string_literal: true
106
+ # source "https://rubygems.org"
107
+
108
+ # ## [ rawfeed ] Do not modify this block unless you know what you are doing.
109
+ # if ENV["RAWFEED_DEV_PATH"] && File.directory?(ENV["RAWFEED_DEV_PATH"])
110
+ # gem "rawfeed", path: ENV["RAWFEED_DEV_PATH"]
111
+ # else
112
+ # ## --- To update rawfeed-jekyll, simply update the version here ---
113
+ # gem "rawfeed", "~> #{Rawfeed::VERSION}"
114
+ # end
115
+
116
+ # # Core
117
+ # gem "jekyll", ">= 4.0", "< 5.0"
118
+ # gem "rake", "~> 13.0"
119
+
120
+ # # Jekyll plugins
121
+ # gem "jekyll-sitemap", "~> 1.4"
122
+ # gem "jekyll-feed", "~> 0.17.0"
123
+ # gem "jekyll-archives", "~> 2.3.0"
124
+ # gem "jekyll-paginate-v2", "~> 3.0.0"
125
+
126
+ # # Utilities
127
+ # gem "colorize", "~> 1.1.0"
128
+ # gem "logger", "~> 1.4"
129
+ # gem "rubyzip", "~> 2.3"
130
+
131
+ # # Build and minification
132
+ # gem "uglifier", "~> 4.2.0"
133
+
134
+ # ## Place your plugins here.
135
+ # # group :jekyll_plugins do
136
+ # # end
137
+
138
+ # # Windows and JRuby
139
+ # platforms :windows, :jruby do
140
+ # gem "tzinfo", "~> 1.2"
141
+ # gem "tzinfo-data"
142
+ # end
143
+
144
+ # # Windows file watcher
145
+ # gem "wdm", "~> 0.1.1", platforms: [:windows]
146
+
147
+ # # Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
148
+ # # do not have a Java counterpart.
149
+ # gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
150
+ # GEMFILE
151
+
152
+ # File.write(File.join(path, "Gemfile"), content)
153
+ # puts "Gemfile created at #{path}".green
154
+ # end
155
+ end
156
+ end
@@ -0,0 +1,138 @@
1
+ require "open3"
2
+ require_relative "../build"
3
+
4
+ module Rawfeed
5
+ # Tooling utilities providing specific CLI build and helper commands.
6
+ # Handles asset minification, cache cleaning, and jekyll lifecycle wrapping.
7
+ module Tools
8
+ # Triggers asset minification (HTML, JS, and image files) within the build site folder.
9
+ # @return [void]
10
+ def self.minify
11
+ Rawfeed::Build::Minifier.minify_all
12
+ end
13
+
14
+ # Cleans the Jekyll cache or the entire generated project.
15
+ # @param args [Array<String>] Command line arguments (e.g., '--cache' or '--all').
16
+ # @return [void]
17
+ def self.clean(*args)
18
+ if args.include?("--cache")
19
+ Rawfeed::Build::Cleaner.clean_jekyll_cache
20
+ elsif args.include?("--all")
21
+ Rawfeed::Build::Cleaner.clean_project
22
+ else
23
+ puts "Missing argument.".red
24
+ puts "Use one of:".yellow
25
+ puts " --all → clean full project"
26
+ puts " --cache → clean only Jekyll cache"
27
+ exit 1
28
+ end
29
+ end
30
+
31
+ # Prints the CLI help documentation to standard output.
32
+ # Exits cleanly.
33
+ # @return [void]
34
+ def self.help
35
+ begin
36
+ puts "rawfeed-jekyll - A batteries-included Jekyll framework and CLI".bold
37
+ puts "\nUsage: rawfeed <command> [options]".yellow
38
+ puts "\nCommands:".bold
39
+ puts " new <path> Create a new rawfeed site"
40
+ puts " Use '.' to create in current directory"
41
+ puts " Add --force to override non-empty directory"
42
+ puts " install Install dependencies (Bundle)"
43
+ puts " build [OPTIONS] Build the site"
44
+ puts " serve [OPTIONS] Run local development server"
45
+ puts " minify Minify JS, HTML and images in _site/"
46
+ puts " (requires ImageMagick for image minification)"
47
+ puts " backup Create a backup of your site"
48
+ puts " Options:"
49
+ puts " -d, --destination PATH Save backup to a specific directory"
50
+ puts " -a, --append PATH Add extra files/folders to backup"
51
+ puts " clean --cache Clean Jekyll cache"
52
+ puts " clean --all Clean entire project"
53
+ puts "\nContent Generators:".bold
54
+ puts " create:draft Create a draft for a post"
55
+ puts " create:page Create a page"
56
+ puts " create:pixel Create a post for pixel"
57
+ puts " restore:resume Restore the resume page (CV)"
58
+ puts " restore:donate Restore the donation page"
59
+ puts " restore:contact Restore the contact page"
60
+ puts " restore:licenses Restore the licenses page"
61
+ puts " post:draft Opens a selector to move drafts to posting"
62
+ puts "\nLayout Commands:".bold
63
+ puts " home:about Set the home page as the about page"
64
+ puts " home:blog Set the home page as the weblog page"
65
+ puts " blog:enable Enable the Blog"
66
+ puts " blog:disable Disables the Blog, leaving only the pages"
67
+ puts " pixels:enable Enable the Pixels"
68
+ puts " pixels:disable Disables the Pixels, leaving only the pages"
69
+ puts "\nOptions:".bold
70
+ puts " For Jekyll build/serve options, run:"
71
+ puts " rawfeed build --help"
72
+ puts " rawfeed serve --help"
73
+ puts "\nFor more info: https://rawfeed.github.io/rawfeed-jekyll".cyan
74
+ rescue Interrupt
75
+ puts "\n[!] Approached by the user".yellow
76
+ exit!
77
+ end
78
+ end
79
+
80
+ # Runs `bundle install` to install ruby dependencies for the generated site.
81
+ # @return [void]
82
+ def self.install
83
+ puts "Installing Ruby gems...".blue
84
+ begin
85
+ success = system("bundle install")
86
+ rescue Interrupt
87
+ puts "\n[!] Approached by the user".yellow
88
+ exit!
89
+ end
90
+
91
+ if success
92
+ puts "Dependencies installed successfully!".green
93
+ else
94
+ puts "[!] bundle install failed".red
95
+ exit 1
96
+ end
97
+ end
98
+
99
+ # Wraps the `jekyll build` command and passes along any specific arguments.
100
+ # Overrides help text to say "rawfeed" instead of "jekyll".
101
+ # @param args [Array<String>] Build arguments to pass to Jekyll.
102
+ # @return [void]
103
+ def self.build(*args)
104
+ if args.include?("--help")
105
+ output, = Open3.capture2(*["bundle", "exec", "jekyll", "build", "--help"])
106
+ puts output.gsub(/jekyll/, "rawfeed")
107
+ else
108
+ begin
109
+ cmd = ["bundle", "exec", "jekyll", "build"] + args
110
+ system(*cmd)
111
+ rescue Interrupt
112
+ puts "\n[!] Approached by the user".yellow
113
+ exit!
114
+ end
115
+ end
116
+ end
117
+
118
+ # Wraps the `jekyll serve` command and passes along any specific arguments.
119
+ # Overrides help text to say "rawfeed" instead of "jekyll".
120
+ # @param args [Array<String>] Serve arguments to pass to Jekyll.
121
+ # @return [void]
122
+ def self.serve(*args)
123
+ if args.include?("--help")
124
+ output, = Open3.capture2(*["bundle", "exec", "jekyll", "serve", "--help"])
125
+ puts output.gsub(/jekyll/, "rawfeed")
126
+ else
127
+ begin
128
+ cmd = ["bundle", "exec", "jekyll", "serve"] + args
129
+ system(*cmd)
130
+ rescue Interrupt
131
+ puts "\n[!] Approached by the user".yellow
132
+ exit!
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+
@@ -10,18 +10,18 @@ module Jekyll
10
10
  priority :low
11
11
 
12
12
  def generate(site)
13
- options_yml = File.join(site.source, "_data", "options.yml")
13
+ generic_yml = File.join(site.source, "_data", "generic.yml")
14
14
 
15
- unless File.exist?(options_yml)
16
- Jekyll.logger.error "[AuthorPlugin]", "File _data/options.yml not found!"
15
+ unless File.exist?(generic_yml)
16
+ Jekyll.logger.error "[AuthorPlugin]", "File _data/generic.yml not found!"
17
17
  return
18
18
  end
19
19
 
20
- options_data = YAML.load_file(options_yml)
21
- author_value = options_data["author"]
20
+ generic_data = YAML.load_file(generic_yml)
21
+ author_value = generic_data["author"]
22
22
 
23
23
  unless author_value
24
- Jekyll.logger.warn "[AuthorPlugin]", "Field 'author' not found in options.yml."
24
+ Jekyll.logger.warn "[AuthorPlugin]", "Field 'author' not found in generic.yml."
25
25
  return
26
26
  end
27
27
 
@@ -41,7 +41,7 @@ module Jekyll
41
41
 
42
42
  if content =~ /^author:\s*.+$/
43
43
  updated = content.gsub(/^author:\s*.+$/, "author: \"#{author_value}\"")
44
- elsif content =~ /\A---\s*\n/ # insere logo depois do primeiro ---
44
+ elsif content =~ /\A---\s*\n/
45
45
  updated = content.sub(/\A(---\s*\n)/, "\\1author: \"#{author_value}\"\n")
46
46
  end
47
47
 
@@ -0,0 +1,51 @@
1
+ #encoding: utf-8
2
+
3
+ require "colorize"
4
+ require "fileutils"
5
+ require "rubygems"
6
+ require_relative "../core/utils"
7
+
8
+ module Rawfeed
9
+ class Contact
10
+ def self.restore_page
11
+ Rawfeed::Utils.create_directory(Rawfeed::CONFIG['PAGES_DIR'])
12
+ slug = "contact"
13
+ filepath = File.join(Rawfeed::CONFIG['PAGES_DIR'], "#{slug}.#{CONFIG['markdown_extension']}")
14
+
15
+ # capture ctrl+c
16
+ trap("INT") do
17
+ puts "\n[!] Operation canceled by user (Ctrl+C).".yellow
18
+ exit!
19
+ end
20
+
21
+ if File.exist?(filepath)
22
+ answer = Rawfeed::Utils.confirm("#{filepath} already exists. Do you want to overwrite?")
23
+ abort("Operation canceled by user.") if answer == 'n'
24
+ end
25
+
26
+ File.open(filepath, 'w') do |file|
27
+ file.puts("---")
28
+ file.puts("layout: contact")
29
+ file.puts("author: # \"Your Name\"")
30
+ file.puts("title: \"Contact\"")
31
+ file.puts("order: 3")
32
+ file.puts("emoji: ✉️")
33
+ file.puts("in_menu: true")
34
+ file.puts("published: false")
35
+ file.puts("toc:")
36
+ file.puts(" enable: false")
37
+ file.puts("permalink: /contact/")
38
+ file.puts("---")
39
+ file.puts("")
40
+ file.puts "{%- include markdown/details summary=\"Other forms of contact\" -%}"
41
+ file.puts("**You** can contact me in other ways...")
42
+ file.puts("{%- include markdown/enddetails -%}")
43
+ file.puts("")
44
+ end
45
+
46
+ puts "[*] Restore contact #{filepath} successfully!".green
47
+ puts "[!] Note: Remember to set \"published\" to \"true\" to publish.".yellow
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ #encoding: utf-8
2
+
3
+ require "colorize"
4
+ require "fileutils"
5
+ require "rubygems"
6
+ require_relative "../core/utils"
7
+
8
+ module Rawfeed
9
+ class Donate
10
+ def self.restore_page
11
+ Rawfeed::Utils.create_directory(Rawfeed::CONFIG['PAGES_DIR'])
12
+ slug = "donate"
13
+ filepath = File.join(Rawfeed::CONFIG['PAGES_DIR'], "#{slug}.#{CONFIG['markdown_extension']}")
14
+
15
+ # capture ctrl+c
16
+ trap("INT") do
17
+ puts "\n[!] Operation canceled by user (Ctrl+C).".yellow
18
+ exit!
19
+ end
20
+
21
+ if File.exist?(filepath)
22
+ answer = Rawfeed::Utils.confirm("#{filepath} already exists. Do you want to overwrite?")
23
+ abort("Operation canceled by user.") if answer == 'n'
24
+ end
25
+
26
+ File.open(filepath, 'w') do |file|
27
+ file.puts("---")
28
+ file.puts("layout: donate")
29
+ file.puts("author: # \"Your Name\"")
30
+ file.puts("title: \"Donate\"")
31
+ file.puts("order: 4")
32
+ file.puts("emoji: ☕")
33
+ file.puts("in_menu: true")
34
+ file.puts("published: false")
35
+ file.puts("toc:")
36
+ file.puts(" enable: false")
37
+ file.puts("permalink: /donate/")
38
+ file.puts("---")
39
+ file.puts("")
40
+ file.puts "<!-- Implement your catchy text here. -->"
41
+ end
42
+
43
+ puts "[*] Restore donate #{filepath} successfully!".green
44
+ puts "[!] Note: Remember to set \"published\" to \"true\" to publish.".yellow
45
+
46
+ end
47
+ end
48
+ end
@@ -1,24 +1,26 @@
1
1
  #encoding: utf-8
2
2
 
3
3
  require "colorize"
4
- require_relative "utils"
4
+ require_relative "../core/utils"
5
5
 
6
6
  module Rawfeed
7
7
  class Draft
8
8
  def self.draft_create
9
- array = Rawfeed::Utils.enginer(Rawfeed::CONFIG['DRAFTS_DIR'], 'Enter new draft title:', 'draft')
9
+ array = Rawfeed::Utils.engineer(Rawfeed::CONFIG['DRAFTS_DIR'], 'Enter new draft title:', 'draft')
10
10
 
11
11
  puts "Creating new draft: #{array[3]}"
12
12
 
13
13
  File.open(array[3], 'w') do |file|
14
14
  file.puts("---")
15
- file.puts("layout: post")
15
+ file.puts("layout: blog/post")
16
16
  file.puts("author: # \"Your Name\"")
17
17
  file.puts("title: \"#{array[0]}\"")
18
18
  file.puts("description: \"Description of your post\"")
19
19
  file.puts("date: #{array[2]} -0300")
20
20
  file.puts("update_date: ")
21
21
  file.puts("comments: false")
22
+ file.puts("toc:")
23
+ file.puts(" enable: true")
22
24
  file.puts("tags: [tag1, tag2]")
23
25
  file.puts("---")
24
26
  file.puts("")
@@ -0,0 +1,46 @@
1
+ #encoding: utf-8
2
+
3
+ require "colorize"
4
+ require "fileutils"
5
+ require "rubygems"
6
+ require_relative "../core/utils"
7
+
8
+ module Rawfeed
9
+ class Licenses
10
+ def self.restore_page
11
+ Rawfeed::Utils.create_directory(Rawfeed::CONFIG['PAGES_DIR'])
12
+ slug = "licenses"
13
+ filepath = File.join(Rawfeed::CONFIG['PAGES_DIR'], "#{slug}.#{CONFIG['markdown_extension']}")
14
+
15
+ # capture ctrl+c
16
+ trap("INT") do
17
+ puts "\n[!] Operation canceled by user (Ctrl+C).".yellow
18
+ exit!
19
+ end
20
+
21
+ if File.exist?(filepath)
22
+ answer = Rawfeed::Utils.confirm("#{filepath} already exists. Do you want to overwrite?")
23
+ abort("Operation canceled by user.") if answer == 'n'
24
+ end
25
+
26
+ File.open(filepath, 'w') do |file|
27
+ file.puts("---")
28
+ file.puts("layout: licenses")
29
+ file.puts("author: # \"Your Name\"")
30
+ file.puts("title: \"Licenses\"")
31
+ file.puts("in_menu: false")
32
+ file.puts("published: false")
33
+ file.puts("toc:")
34
+ file.puts(" enable: false")
35
+ file.puts("permalink: /licenses/")
36
+ file.puts("---")
37
+ file.puts("")
38
+ file.puts "<!-- Implement the license text here. -->"
39
+ end
40
+
41
+ puts "[*] Restore licenses #{filepath} successfully!".green
42
+ puts "[!] Note: Remember to set \"published\" to \"true\" to publish.".yellow
43
+
44
+ end
45
+ end
46
+ end
@@ -1,12 +1,12 @@
1
1
  #encoding: utf-8
2
2
 
3
3
  require "colorize"
4
- require_relative "utils"
4
+ require_relative "../core/utils"
5
5
 
6
6
  module Rawfeed
7
7
  class Page
8
8
  def self.page_create
9
- array = Rawfeed::Utils.enginer(Rawfeed::CONFIG['PAGES_DIR'], 'Enter new page title:', 'page')
9
+ array = Rawfeed::Utils.engineer(Rawfeed::CONFIG['PAGES_DIR'], 'Enter new page title:', 'page')
10
10
  puts ":: Creating new page: #{array[3]}"
11
11
 
12
12
  permalink = array[0].downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
@@ -21,8 +21,9 @@ module Rawfeed
21
21
  file.puts("date: #{array[2]} -0300")
22
22
  file.puts("update_date: ")
23
23
  file.puts("in_menu: true")
24
- file.puts("reading_time: true")
25
24
  file.puts("published: false")
25
+ file.puts("toc:")
26
+ file.puts(" enable: false")
26
27
  file.puts("permalink: /#{permalink}/")
27
28
  file.puts("---")
28
29
  file.puts("")
@@ -1,24 +1,27 @@
1
1
  #encoding: utf-8
2
2
 
3
3
  require "colorize"
4
- require_relative "utils"
4
+ require_relative "../core/utils"
5
5
 
6
6
  module Rawfeed
7
7
  class Pixel
8
8
  def self.pixel_create
9
- array = Rawfeed::Utils.enginer(Rawfeed::CONFIG['PIXELS_DIR'], 'Enter new pixel title:', 'pixel')
9
+ array = Rawfeed::Utils.engineer(Rawfeed::CONFIG['PIXELS_DIR'], 'Enter new pixel title:', 'pixel')
10
10
 
11
11
  puts "Creating new pixel: #{array[3]}"
12
12
 
13
13
  File.open(array[3], 'w') do |file|
14
14
  file.puts("---")
15
- file.puts("layout: pixel")
15
+ file.puts("layout: pixels/post")
16
16
  file.puts("author: # \"Your Name\"")
17
17
  file.puts("title: \"#{array[0]}\"")
18
18
  file.puts("description: \"Description of your post\"")
19
19
  file.puts("image:")
20
20
  file.puts(" path: # /assets/images/pixels/example.jpg")
21
- file.puts(" caption: ")
21
+ file.puts(" caption: # Caption image")
22
+ file.puts(" width: 100%")
23
+ file.puts("toc:")
24
+ file.puts(" enable: false")
22
25
  file.puts("date: #{array[2]} -0300")
23
26
  file.puts("---")
24
27
  file.puts("")
@@ -0,0 +1,107 @@
1
+ #encoding: utf-8
2
+
3
+ require "colorize"
4
+ require_relative "../core/utils"
5
+
6
+ module Rawfeed
7
+ class Post
8
+ def self.post
9
+ drafts = Dir.glob(File.join(Rawfeed::CONFIG['DRAFTS_DIR'], "*.#{Rawfeed::CONFIG['markdown_extension']}"))
10
+
11
+ if drafts.empty?
12
+ puts "No files found in #{Rawfeed::CONFIG['DRAFTS_DIR']}".yellow
13
+ return
14
+ end
15
+
16
+ puts "Select the file to move:\n".cyan
17
+
18
+ drafts.each_with_index do |file, index|
19
+ puts "#{index + 1} - #{File.basename(file)}"
20
+ end
21
+ puts "#{drafts.size + 1} - move all"
22
+ puts "#{drafts.size + 2} - cancel"
23
+ print "\nEnter option number: ".cyan
24
+
25
+ # capture ctrl+c
26
+ trap("INT") do
27
+ puts "\n[!] Operation canceled by user (Ctrl+C).".yellow
28
+ exit!
29
+ end
30
+
31
+ choice = STDIN.gets.strip.to_i
32
+
33
+ if choice == drafts.size + 1
34
+ drafts.each { |file| move_file(file) }
35
+ puts "\n[*] All drafts have been moved to #{Rawfeed::CONFIG['POSTS_DIR']}".green
36
+ elsif choice == drafts.size + 2
37
+ puts "\n[!] Operation canceled by user.".yellow
38
+ exit!
39
+ elsif choice.between?(1, drafts.size)
40
+ move_file(drafts[choice - 1])
41
+ else
42
+ puts "\n[x] Invalid option.".red
43
+ end
44
+ end
45
+
46
+ def self.move_file(file)
47
+ filename = File.basename(file)
48
+ destination = File.join(Rawfeed::CONFIG['POSTS_DIR'], filename)
49
+
50
+ if File.exist?(destination)
51
+ puts "[!] The file #{filename} already exists in #{Rawfeed::CONFIG['POSTS_DIR']}".yellow
52
+ return
53
+ end
54
+
55
+ FileUtils.mv(file, destination)
56
+ puts "[*] #{filename} moved to #{Rawfeed::CONFIG['POSTS_DIR']}".green
57
+
58
+ end
59
+ end
60
+
61
+ # Post List
62
+ class PostList
63
+ def self.display
64
+ directory_base = Rawfeed::CONFIG['POSTS_DIR']
65
+ posts = Dir.glob(File.join(directory_base, "*.{md,markdown}"))
66
+
67
+ # Capture arguments in format --key=value
68
+ args = {}
69
+ parsed_args = ARGV.dup
70
+ parsed_args.each do |arg|
71
+ if arg =~ /--([^=]+)=(.*)/
72
+ args[$1] = $2
73
+ end
74
+ end
75
+
76
+ filter_tag = args['tag'] ? args['tag'].downcase : nil
77
+ filter_date = args['date']
78
+
79
+ puts "\n" + "Blog Posts List".bold.blue
80
+ puts "Filters: Tag: #{filter_tag || 'None'} | Date: #{filter_date || 'None'}".cyan
81
+ puts "-" * 90
82
+
83
+ posts.sort.reverse_each do |file|
84
+ begin
85
+ content = File.read(file)
86
+ if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
87
+ data = YAML.safe_load($1, permitted_classes: [Time, Date])
88
+
89
+ title = data['title'] || "No Title"
90
+ published = data['published'] != false ? "YES".green : "NO".red
91
+ tags = data['tags'] || []
92
+ date = data['date'].to_s.split(' ').first || "No Date"
93
+
94
+ next if filter_tag && !tags.map(&:downcase).include?(filter_tag)
95
+ next if filter_date && date != filter_date
96
+
97
+ tag_list = tags.empty? ? "none" : tags.join(", ")
98
+ printf("%-12s | %-3s | %-30s | %s\n", date.cyan, published, title[0..28].ljust(30), tag_list.magenta)
99
+ end
100
+ rescue => e
101
+ puts "[x] Error reading #{file}: #{e.message}".red
102
+ end
103
+ end
104
+ puts "-" * 90
105
+ end
106
+ end
107
+ end