Skip to content

Instantly share code, notes, and snippets.

@jeremyredhead
Last active March 25, 2020 03:24
Show Gist options
  • Save jeremyredhead/534c2f1502b6b95294959d3f72f41342 to your computer and use it in GitHub Desktop.
Save jeremyredhead/534c2f1502b6b95294959d3f72f41342 to your computer and use it in GitHub Desktop.
WIP Ruby Code for Eventual Use in a Markdown Parser
=begin title
EXCESSIVELY ANNOTATED WORK IN PROGRESS RUBY CODE FOR EVENTUAL USE IN A HOMEMADE MARKDOWN PARSER
=end # title
# half-baked WIP for a markdown generator i am fixin' to write
# (for personal use, this thing will make orignal markdown.pl look clean :P)
class Element
# attr_* methods are library helpers,
# they create setters & getters which correspond to a @ClassVar of the same name
attr_accessor :tagname
attr_accessor :contents # i should rename this :children
# the method is initialize, but you don't call it directly :P
# you call :new (which is defined on Object) which creates & allocates an object,
# and then calls initialize with the right self/args
def initialize(tag, node = nil) # default tagname ?
# in this case I am using explicit (instead of implicit) self,
# to invoke the setter (otherwise ruby thinks its a normal variable)
self.tagname = tag
@contents = []
# << is basically push
# notice the elegant but slightly confusing reverse if/unless
self << node unless node.nil?
end
# ruby's version of setters basically
def tagname=(tag)
# sidenote: ruby has some *really* nice regex syntax imho
unless tag.match /^[-_a-z:0-9]+$/
# reminder that ruby uses implicit self, inspect == self.inspect
raise ArgumentError, "bad tagname: '#{tag}' for #{inspect}"
end
@tagname = tag
# do SOMETHING if tag is e.g. 'img' or other weird stuff
end
# yes, that's ruby's name for toString...
def to_s
# that's really ugly looking, isn't it?
# but not as ugly as "<#@tagname>" :D
html = "<#{@tagname}>"
# oh yea also ruby has mutable strings. yea
@contents.each { |node| html << node.to_s }
html << "</#{@tagname}>"
end
# inspect is called by IRB
def inspect
# TODO: better inspect
"<#{@tagname}> #{@contents[0]} ..."
end
# i wish JS had operator overloading....
def <<(node)
@contents << node
self
end
# this is a little confusing (even *if* you know ruby)...
# this is "static" class method b/c of the `self.`
# "but wait?", i hear myself say to no one,
# "i thought ruby was implicit self? why is this different from above"
# well, uh, normally methods are defined on the class (Element)
# ...but not the object Element(?)
# but with self, you're defining it on Element, aka Element's class
# no, not Class, the Element object's *metaclass*...
# look, just read this, okay?
# i can barely keep it all straight in my own head...
# https://yehudakatz.com/2009/11/15/metaprogramming-in-ruby-its-all-about-the-self/
def self.method_missing(name, *args)
# TODO: use an element tagname white-list
# this is very lazy. super to catch errors
super unless name.match(/^[a-z][a-z0-9]*$/)
new(name, *args)
end
# after some reading & research i realized in this case,
# probably i would want to use define_method,
# since the list of html elements doesn't change too often :P
end
# stuff from Kernel can be called anywhere un-namespaced
# it holds stuff like print, puts, gets, etc
module Kernel
def h(tag, node = nil)
Element.new(tag, node)
end
end
class Document
def initialize; end
end
__END__
Note: __END__ marks the beginning of the "data section" in a ruby file
(which can be read by the program!)
IIRC this is one of the features copied from Perl :P
# NOTES
/ html | body | title # etc
| h[1-6]
| [abipqsu]
| a | abbr | b | br | em | strong
| blockquote | ins | del | figure | figcaption | /x
# is this a bad idea?
# thinking bout whether to alias these method names to elements
# just to make the code prettier, y'know
strike = s
bold = b
italic = i
under(line) = u
quote = q
super = sup
? link = a
image = img
para = p
%w[ html head body title
h1 h2 h3 h4 h5 h6
dl ol ul dd dt li
a abbr b br cite code em i mark s sub sup time u
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment