Perc is finsished

Massive work done. Finished in that the criteria of what it wanted to
do is done, still lot of refining left.

Added directory-local toml, local routing support
This commit is contained in:
Pranshu Sharma 2025-06-01 13:01:59 +10:00
parent 094189e2cb
commit 50152e4abf
2 changed files with 100 additions and 66 deletions

View file

@ -12,3 +12,6 @@ gem 'tomlib'
# embeded ruby templating lanuage # embeded ruby templating lanuage
gem 'erb' gem 'erb'
# database
gem 'activerecord'

163
app.rb
View file

@ -5,14 +5,15 @@ require 'nokogiri'
require 'redcarpet' require 'redcarpet'
require 'tomlib' require 'tomlib'
$markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, tables: true)
$root = "/home/pranshu/Documents/proj/perc/test" $root = "/home/pranshu/Documents/proj/perc/test"
Dir.chdir $root; Dir.chdir $root;
class Config class Config
attr_reader :approved_regex, :layout attr_reader :approved_regex, :layout
def initialize def initialize
approved_files = [/\.md$/, /\.erb$/] approved_files = [/\.md$/, /\.e?rb$/]
@approved_regex = Regexp.union(approved_files) @approved_regex = Regexp.union(approved_files)
toml = Tomlib.load(File.read "config.toml") toml = Tomlib.load(File.read "config.toml")
@ -26,8 +27,8 @@ $config = Config.new();
class Sidebar class Sidebar
attr_reader :tree attr_reader :tree
FileNode = Struct.new(:type, :path, :name) FileNode = Struct.new(:type, :path, :name, :real)
DirNode = Struct.new(:type, :path, :name, :files) DirNode = Struct.new(:type, :path, :name, :files, :index, :rb_file)
def initialize def initialize
@tree = process_dir "." @tree = process_dir "."
@ -49,7 +50,13 @@ class Sidebar
builder = Nokogiri::HTML::Builder.new do |doc| builder = Nokogiri::HTML::Builder.new do |doc|
def deal_with_dir (doc, dir, path) def deal_with_dir (doc, dir, path)
doc.li { doc.li {
doc.text dir.path if dir.index
doc.a(:href => "/" + path + "/") {
doc.text dir.path
}
else
doc.text dir.path
end
doc.ul { doc.ul {
dir.files.each do |f| dir.files.each do |f|
fpath = File.join(path, f.path) fpath = File.join(path, f.path)
@ -68,7 +75,9 @@ class Sidebar
deal_with_dir doc, @tree, @tree.path deal_with_dir doc, @tree, @tree.path
} }
end end
@html = builder.to_html().split(/\n/)[1..-1].join # colossus hack, but its fine for perf cause we cache
doc = Nokogiri::HTML(builder.to_html())
@html = doc.children[1].child.child.child.children[1].to_s
end end
private private
@ -89,22 +98,74 @@ class Sidebar
end end
def process_dir(dir) def process_dir(dir)
DirNode.new(:dir, dir, getname(dir), index = false
Dir.chdir(dir) do rb_file = false
dn = DirNode.new
dn.type = :dir
dn.files = []
temp = Dir.chdir(dir) do
ignored = false
if File.file? ".perc.toml"
toml = Tomlib.load(File.read ".perc.toml")
toml["routes"].each do |route|
name = route[0]
url = route[1]
dn.files.push(FileNode.new(:fil, url, name, false))
end
ignored = toml["ignore"] || false
ignored = Regexp.union(ignored)
end
dir_files.map do |f| dir_files.map do |f|
if File.file? f if File.file? f
FileNode.new(:file, f, getname(f)) if f =~ /index\.(erb|md)$/
index = f
next nil
elsif f =~ /\.rb$/
rb_file = f
next nil
else
if ignored and f =~ ignored
next nil
end
next FileNode.new(:file, f, getname(f), true)
end
else else
process_dir f next process_dir f
end end
end end
end) end
dn.files = temp.collect + dn.files
dn.files = dn.files.compact
dn.path = dir
dn.rb_file = rb_file
dn.name = dn.path
dn.index = index
# Read dir local config
dn
end end
end end
$sidebar = Sidebar.new $sidebar = Sidebar.new
def pview(file)
body = ""
cont = File.read(file) or return "Not found"
if (file =~ /\.erb$/)
tp = ERB.new(cont)
body = tp.result(binding)
elsif (file =~ /\.md$/)
body = $markdown.render cont
end
put_in_layout(body)
end
Dir["./**/*.rb"].each { |f| load(f) }
def put_in_layout (str)
body = str
tree = $sidebar.html
ERB.new(File.read($config.layout)).result(binding)
end
class App < Roda class App < Roda
@ -118,67 +179,37 @@ class App < Roda
end end
# Now the saga begins,we transform file_tree into a routing tree # Now the saga begins,we transform file_tree into a routing tree
def process_dir (r, dir, cdir) def process_dir (r, dir, cdir)
p = Proc.new do p = Proc.new do
dir.files.each do |f| dir.files.each do |f|
dd = File.join(cdir, f.path) dd = File.join(cdir, f.path)
if f.type == :dir if f.type == :dir
# f is dir # f is dir
process_dir r, f, dd process_dir r, f, dd
else elsif f.real == true
# f is a file # f is a file and is real
r.get f.path do r.get f.path do
pview dd pview dd
end
end end
end end
"Whatup"
end end
if dir.path == "." if dir.index
p.call r.is "" do
else pview File.join(cdir, dir.index)
r.on dir.path do
p.call
end end
end end
rf = dir.rb_file
if rf
eval "r.run #{File.basename(rf,File.extname(rf)).capitalize}"
end
end
if dir.path == "."
p.call
else
r.on dir.path do
p.call
end
end end
def tree
$sidebar.html
end
def pview(file)
layout = $config.layout
tp = ERB.new(File.read(file))
body = tp.result(binding)
ERB.new(File.read(layout)).result(binding)
end end
end end
# class Perc < Sinatra::Application
# set :views, "."
# set :markdown, :layout_engine => :erb
# # @sidebar = Sidebar.new
# get "/" do
# erb :main, layout: $config.layout
# end
# get "/*.*" do |path, ext|
# if ext == "md"
# md = markdown File.read(path + ".md"), layout: $config.layout
# else
# erb path.to_sym, layout: $config.layout
# end
# end
# helpers do
# def tree
# $sidebar.html
# end
# end
# end