How can I deactivate some Markdown parsing rules in Mistune?
For instance I would like enable only **bold** and *italic* and deactivate all other rule parsing.
Is that possible?
You need to create a custom renderer.
A renderer is a class and each rule is a method of that renderer class.
To have your own rules, you need to either override a method and make it do nothing (Method A below), or to replace the full list of default_rules (method B below)
Method A)
Override a rule method: Here is the full list of rules.
E.G.:
class YourRenderer(mistune.Renderer):
#example of rule
def block_code(self, code, lang):
pass
renderer = YourRenderer()
markdown = mistune.Markdown(renderer=renderer) # this renderer won't have the block_code rule
Method B)
Tamper with default_rules array
A renderer has an own property called default_rules. You just need to create a custom renderer and modify that array to your liking. Here's a sample class to get you started
class CustomRenderer(InlineLexer):
# Modify this array as you like
# you can insert or delete whatever rules it has
self.default_rules.insert(3, 'some_function')
I didn't test this
Related
Context: I'm implementing a Jenkins Pipeline. For this, in order to define the pipeline's parameters I implemented the DSL file.
In the DSL file, I have a parameter of ActiveChoiceParam type, called ORDERS. This parameter will allow me to choose one or more orders numbers at the same time.
Problem: What I want to do is to set the values that gets rendered for ORDERS parameter from a custom library. Basically I have a directory my_libraries with a file, orders.groovy. In this file, there is an order class, with a references list property that contains my values.
The code in the DSL file is as follows:
def order = new my_libraries.order()
pipelineJob("111_name_of_pipeline") {
description("pipeline_description")
keepDependencies(false)
parameters {
stringParam("BRANCH", "master", "The branch")
activeChoiceParam("ORDERS") {
description("orders references")
choiceType('CHECKBOX')
groovyScript{
script("return order.references")
fallbackScript("return ['error']")
}
}
}
}
Also, is good to mention that my custom library works well. For example, if I choose to use a ChoiceParam as below, it works, but of course, is not the behaviour I want. I want to select multiple choices.
choiceParam("ORDERS", order.references, "Orders references list but single-choice")
How can I make order.references available in the script part of groovyScript?
I've tried using global instance of order class, instantiate the class directly in the groovyScript, but no positive result.
I want to dynamically add a field and methods to the metaClass of my current object. I tried
this.metaClass.testProp = "test"
to add a field called testProp. However, I get
groovy.lang.MissingPropertyException: No such property: testProp for class: groovy.lang.MetaClassImpl
When I do the same on class level, e.g. adding testProp to the class and not directly to the object
Process.metaClass.testProp = "test"
it works, but my object does NOT inherit the field. Any ideas or pointers in the right direction would be greatly appreciated.
Short answer:
Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"
Long answer:
I assume, there are 3 things that make you a problem here. The first one is that there is a global registry for meta classes. The second is that Groovy allowed per instance meta classes (and this is the default for Groovy classes). And the third one is that the default meta class does not allow runtime meta programming.
So what happens if you do runtime meta programming is that the default needs to replaced by ExpandoMetaClass (EMC), to allow for that. But since there is a per instance meta class logic, this replacement may not affect all instances. The meta class of the instance is taken from the global registry the first time it is used. Process.metaClass.testProp = "test" changes the global saved one. Any instance that already has a meta class, will not know of the change and thus not know the property. this.metaClass.testProp = "test" will change only the meta class of the current instance, other instances may not know of it. You can use this.metaclass = null to reset it. And it will again request the meta class from the global registry.If you did the per instance change, your change is away. If you did the global change, your change is visible now.
All this counts if you work with the default meta class in Groovy (MetaClassImpl). If you do a change like a in your code, the new meta class will be ExpandoMetaClass (EMC). This meta class allows for changes, so further changes will not cause a replacement of the meta class. To ensure all instance take an ExpandoMetaClass from the beginning you normally have some kind of setup code like this: ExpandoMetaClass.enableGlobally()
So to solve your question I could simply do this
Process.metaClass.testProp = "test"
this.metaClass = null
assert this.testProp == "test"
If you used ExpandoMetaClass.enableGlobally() in some setup code before, you can leave the reset code for the meta class out (or if the global meta class is the same as the one for "this" and if it is EMC). Grails for example uses EMC as default
How do I supply a configured value to a #view_config-decorated function or class?
E.g.
#view_config(route_name='example', renderer=some_config['template.name'])
class MyClass(BaseView):
...
Or
#view_defaults(route_name='example', renderer=some_config['template.name2'])
class MyClass2(BaseView):
...
Or
#view_config(route_name='example', renderer=some_config['template.name3'])
def method3(request):
...
It's very hard to know where to start, as I'm trying to edit a pyramid plugin, which pulls together its config in an includeme function, so it doesn't have anything obvious that I can include, and it's hard to know what's available to the #view_config decorator.
You can add views using declarative configuration (what you are doing now using #view_config or alternatively using imperative configuration by calling config.add_view() method.
In this case, as you need to access the Pyramid registry and settings file, it is easier to do adding the views imperatively.
In your __init__.py you can do:
settings = config.registry.settings
# You need to call config.add_route("foobar") to map view to URL also
config.add_view('views.MyClass', route_name="foobar", renderer=settings['template.name3'])
Then in your views.py:
class MyClass(BaseView):
pass
#view_config() and add_view() arguments are equal.
I thin kyou can also mix view_config and add_view() arguments for the same view, but I am not sure aobut this. Hope this helps.
I am building a QWidget in PySide, and running into an issue when trying to share data between pages.
To summarize I utilize user inputs from earlier pages to construct a list of custom objects, which I need to share with the following page.
At the beginning of my code I construct a custom object, with an attribute called .name (among other attributes)
class MyCustomClass():
def __init__(self, name, other_attributes)
self.name = name
...set other attributes
In my QWizard I open a file and make a list of names to match with another list of MyCustomClass objects. I then display the names alongside the matched name of the corresponding MyCustomClass object and prompt the user to confirm (or change), before moving to the next page.
Each match is stored as a tuple(name, MyCustomClass) and added to a list. I then wish to read this list from the next page in order to perform more operations. I'm trying to use .registerField, but I'm unsure of how to properly do so. My attempt is below.
First I make a QWizardPage, perform some code and then construct my matches. I made a function to return the value and used this for the .registerField
class ConfirmMatches(QWizardPage):
def __init__(self):
...
def initializePage(self):
# Code to make display and operations and make list of matches
...
self.matches = matches
self.registerField("matches", self, "get_matches")
def get_matches(self):
return self.matches
Then from my next page, I try to call the field, but I only return a None object.
class NextPage(QWizardPage):
def __init__(self):
...
def initializePage(self):
# Get relevant fields from past pages
past_matches = self.field("matches")
type(past_matches) is None, even though when I print self.matches in the previous page it clearly displays them all.
What am I doing wrong with the registerField?
Is there an easier way to share this type of data between pages?
I actually solved it myself. I was on the right track, just missing a few things, but I'll catalog here for anyone else with similar problems.
Like I said I have a list of matched objects, where each match is a list of a name, and the object that was found to correspond to that name, i.e. match = [name, MyCustomClass]
class ConfirmMatches(QWizardPage):
# Function to change list
def setList(self, new_list):
self.list_val = new_list
if self.list_val != []:
self.list_changed.emit()
# Function to return list
def readList(self):
return self.list_val
def __init__(self):
self.list_val = [] # Create initial value
# Code to initialize displays/buttons, and generate matches
...
# Here I assign the matches I made "matches", to the QProperty "match_list"
self.setList(matches)
# Then register field here.
# Instead of the read function, I call the object itself (not sure why, but it works)
self.registerField("registered_list", self, "match_list")
# Define "match_list" as a QProperty with read and write functions, and a signal (not used)
match_list = Property(list, readList, setList)
listChanged = Signal()
I made the list a QProperty and wrote the Read and Write functions, as well as a Signal (not used). Then, when registering the field, instead of putting the Read function (readList), I put the QProperty itself (match_list). Not sure why it works, but this conceivable could be used to register other custom objects.
If you want to explicitly set the value of the field matches in your ConfirmMatches page, you would need to do one of a few things:
Make an explicit call to self.setField any time your matches change.
Emit a signal every time your matches are changed after registering the property
Store your matches in one of the standard Qt inputs, like QLineEdit, and use that widget in the registerField call.
If you check the docs for QWizardPage.registerField, what it does is register to grab the named property of the passed in widget when the widget's signal is emitted. The way your code is now, you would need to add a signal to your ConfirmMatches page that would be emitted whenever your matches variable changes. Otherwise, your page doesn't know when the field should be updated.
When processing my ANTLR4 parse tree by a visitor, sometimes I need to know the parent rule nodes that my rule node is under. In the online API documentation for ParserRuleContext, I find no method/field that can return the name of the rule that an object is representing. I know the rule name is part of the ParserRuleContext's subclass name e.g. function_definition rule node is class Function_definitionContext. But to enquire the class name I need to use Java reflection and manually stripe the Context string at the end.
Is there is simpler method to retrieve the rule name that a ParserRuleContext object is representing?
It is a common requirement to enquire the parent rule node's name. For example, when processing the C++ grammar, a C++ class declaration can be in a global scope, function definition, or another class declaration which means a rule node class_declaration can be nested under a global_scope, function_definition or class_declaration rule node. If I want to isolate only those class_declaration nodes under the global_scope, I need to look up the parent nodes and make sure that they're not function_definition or class_declaration.
To get the rule name from a ParserRuleContext as a string, you can do this:
String[] ruleNames = parser.getRuleNames();
String ruleName = ruleNames[parserRuleContext.getRuleIndex()];
You can also compare the rule index against the generated constants:
boolean isClassDeclaration =
parserRuleContext.getRuleIndex() == MyParser.RULE_class_declaration;