Basic parser implementation
This commit is contained in:
		
							
								
								
									
										1
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Gemfile
									
									
									
									
									
								
							@@ -6,6 +6,7 @@ source "https://rubygems.org"
 | 
			
		||||
gemspec
 | 
			
		||||
 | 
			
		||||
gem "rake", "~> 13.0"
 | 
			
		||||
gem "rackup"
 | 
			
		||||
 | 
			
		||||
gem "rspec", "~> 3.0"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								Gemfile.lock
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										99
									
								
								lib/skeksis/parser.rb
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user