Basic parser implementation

This commit is contained in:
maddiebaka 2023-08-01 22:53:54 -04:00
parent 7e0640dc1c
commit b150a808ab
6 changed files with 178 additions and 32 deletions

View File

@ -6,6 +6,7 @@ source "https://rubygems.org"
gemspec
gem "rake", "~> 13.0"
gem "rackup"
gem "rspec", "~> 3.0"

View File

@ -1,41 +1,82 @@
PATH
remote: .
specs:
skeksis (0.1.0)
GEM
remote: https://rubygems.org/
specs:
eventmachine (1.2.7)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
faraday-detailed_logger (1.0.0)
faraday
faraday_middleware (0.14.0)
faraday (>= 0.7.4, < 1.0)
faye-websocket (0.10.9)
eventmachine (>= 0.12.0)
websocket-driver (>= 0.5.1)
gemini-rb (0.0.2)
eventmachine (~> 1.0, >= 1.0.9.1)
faraday (~> 0.9.2, >= 0.9.2)
faraday-detailed_logger (~> 1.0.0, >= 1.0.0)
faraday_middleware (~> 0.10, >= 0.10.0)
faye-websocket (~> 0.10.3)
json (~> 1.8.3, >= 1.8.3)
json (1.8.6)
multipart-post (2.3.0)
ast (2.4.2)
diff-lcs (1.5.0)
json (2.6.3)
language_server-protocol (3.17.0.3)
lint_roller (1.1.0)
parallel (1.23.0)
parser (3.2.2.3)
ast (~> 2.4.1)
racc
racc (1.7.1)
rack (3.0.8)
rackup (2.1.0)
rack (>= 3)
webrick (~> 1.8)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.8.1)
rexml (3.2.6)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
rubocop (1.52.1)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.2.3)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.29.0)
parser (>= 3.2.1.0)
rubocop-performance (1.18.0)
rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0)
ruby-progressbar (1.13.0)
standard (1.30.1)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0)
rubocop (~> 1.52.0)
standard-custom (~> 1.0.0)
standard-performance (~> 1.1.0)
standard-custom (1.0.2)
lint_roller (~> 1.0)
rubocop (~> 1.50)
standard-performance (1.1.2)
lint_roller (~> 1.1)
rubocop-performance (~> 1.18.0)
unicode-display_width (2.4.2)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
PLATFORMS
arm64-darwin-22
DEPENDENCIES
gemini-rb
rack
rackup
rake (~> 13.0)
rspec (~> 3.0)
skeksis!
standard (~> 1.3)
BUNDLED WITH
2.4.15

View File

@ -1,4 +1,6 @@
SERVE_DIR="/Volumes/Exodrive/Code/gemini-bridge-rack/skeksis/pub_gemini"
require 'skeksis'
SERVE_DIR="/Users/madeline/Code/gemini-bridge-rack/gemini"
class SkeksisApp
def call(env)
@ -15,7 +17,9 @@ class SkeksisApp
return Dir.each_child(path).map {|i| "#{i}\n"}
elsif File.exist?(path)
file = File.open(path, 'r')
file.readlines
data = file.readlines
Skeksis::Parser.parse(data)
data
else # path is invalid
return nil
end

View File

@ -1,6 +1,7 @@
# frozen_string_literal: true
require_relative "skeksis/version"
require_relative "skeksis/parser"
module Skeksis
class Error < StandardError; end

99
lib/skeksis/parser.rb Normal file
View File

@ -0,0 +1,99 @@
# Code adapted from MIT-licensed gemini-rb project
# parser.rb hosted at
# https://github.com/genenetwork/gemini-rb/blob/main/lib/gemini-rb/parser.rb
module Skeksis
module Parser
extend self
def parse(input)
puts("##### PARSING STARTED #####")
list = []
data = input.map(&:chomp)
in_verbatim_block = false
data.each do |line|
type = get_type(line)
if type == :verbatim and in_verbatim_block == false
in_verbatim_block = true
elsif type == :verbatim
in_verbatim_block = false
end
if in_verbatim_block == true
list.push({ type: :verbatim, content: [line] })
else
list.push({ type: type, content: [line] })
end
end
puts strip_markers(list)
puts("##### PARSING FINISHED #####")
end
private
def strip_markers(gemtext)
gemtext.map do |line|
type = line[:type]
content = line[:content]
text = content[0]
case type
when :blank
#{ type: type, content: nil }
{ type: type }
when :header
m = /^(#+)(\s*)(.*)/.match(text)
level = m[1].count("#")
{ type: type, level: level, content: [m[3]] }
when :list
{ type: type, content: content.map { |t| t.sub(/^\*\s*/, "") } }
when :quote
{ type: type, content: content.map { |t| t.sub(/^\>\s?/, "") } }
when :uri
a = text.sub(/^=>\s*/, "").split(" ", 2)
link = a[0]
text = a[1]
{ type: type, link: link, text: text }
when :verbatim
# TODO: Match with syntax highlighting, maybe
m = /^```(.*)/.match(text)
unless m.nil?
nil
else
{ type: type, content: content }
end
else
{ type: type, content: content }
end
end.compact
end
def get_type(l)
case l
when ""
:blank
when /^#/
:header
when /^\*/
:list
when /^\>/
:quote
when /^\=>/
:uri
when /^```/
:verbatim
else
:text
end
end
def parse_line(line)
end
end
end

View File

@ -8,16 +8,16 @@ Gem::Specification.new do |spec|
spec.authors = ["maddiebaka"]
spec.email = ["madeline@cray.lgbt"]
spec.summary = "TODO: Write a short summary, because RubyGems requires one."
spec.description = "TODO: Write a longer description or delete this line."
spec.homepage = "TODO: Put your gem's website or public repo URL here."
spec.summary = "An http->gemini bridge in ruby"
#spec.description = "TODO: Write a longer description or delete this line."
spec.homepage = "https://maddie.info"
spec.required_ruby_version = ">= 2.6.0"
spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
#spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
#spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
#spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.