-
Notifications
You must be signed in to change notification settings - Fork 744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add Lexer#with, for specifying options after initialization #1188
Conversation
I like the idea of being able to reinitialize a Lexer with a new set of options. However, there might be something even simpler for the use case at hand, which I'll describe. The difficulty with Basically, we're looking to control this line: lexer_class && lexer_class.new(additional_options) Here's how that might look in practice: start_inline_if_php = ... # user-defined
lexer = Lexer.find_fancy lang do |lexer_class, opts|
if lexer_class.tag == 'php' && start_inline_if_php
opts[:start_inline] = true
end
lexer_class.new opts
end We get all the benefits of |
I should add that this would dovetail really nicely with guess too, when you absolutely have no idea what lexer you're going to get. You would now have a callback post-guess to react to the result. |
In this latest commit, I've factored out a method called lexer_class, opts = Lexer.lookup_fancy(lang)
lexer_class ||= Rouge::Lexers::PlainText
if lexer_class.tag == 'php' && start_inline_if_php
# use string keys for lexer options (lexer option keys are user-provided, thus unsafe for symbols)
# and use reverse_merge in case of a manual start_inline=false in the CGI options
opts.reverse_merge!('start_inline' => true)
end
lexer_class.new(opts) |
If you don't have |
I will, however, note that a Lexer instance and a pair of lexer class and options are not that different when you get right down to it... |
# | ||
def find_fancy(str, code=nil, additional_options={}) | ||
|
||
# Rlease note: the lexer class might be nil! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo here:
# Rlease note: the lexer class might be nil! | |
# Release note: the lexer class might be nil! |
What's the argument against the block argument? That seems to me like the more idiomatic way to do it in Ruby. And it's already used throughout the Rouge API. Returning multiple arguments from a function is always a bit awkward, especially in comparison. I'd make the case that the block shouldn't be called if no lexer is resolved. |
I didn't intend to split the discussion across two PRs. The fact the suggestions to @jneen's solution are visible in the PR list for Rouge is an unfortunate side effect of this branch being in the Rouge project. Here's the explanation for my suggested changes:
Please discuss here rather than in #1195. |
@pyrmont Can you do a |
3c54f92
to
451b978
Compare
@jneen Should this branch be reworked to be part of the v4.0 release? |
Superseded by #1565. |
cc @mojavelinux
A common use case is to want to set options on the return value of something like
Lexer.find_fancy
, which returns an instance rather than a class. While in the future we may want to allow those options to be passed to the#lex
method, we must wait for a major version release to clear the deprecation of the:continue
option.In the meanwhile, since lexer initializers are uniform, we can provide a method
:with
that returns a cloned lexer with extra options, which should satisfy most use cases.