Adding classes to headers with a Pandoc lua filter - templates

I'm putting together a Quarto template for Springer Nature journals. The LaTeX document class has some frustrating aspects that I'm trying to circumvent with lua filters so the template can be used as much as possible with vanilla markdown. One such filter (inspired by this discussion) takes any heading with the class {.backmatter} and for the PDF format, uses \bmhead* instead of \section; this bit works as expected:
local backmatter_inserted = false
function Header(el)
if quarto.doc.isFormat("pdf") then
if not backmatter_inserted and el.classes:includes("backmatter") then
backmatter_inserted = true
el.content = pandoc.utils.stringify(el.content)
return {
pandoc.RawBlock('tex', '\\backmatter'),
pandoc.RawBlock('tex', '\\bmhead*{' .. el.content .. '}')
}
elseif el.classes:includes("backmatter") then
el.content = pandoc.utils.stringify(el.content)
return pandoc.RawBlock('tex', '\\bmhead*{' .. el.content .. '}')
end
elseif quarto.doc.isFormat("html") and el.classes:includes("backmatter") then
el.classes:insert("appendix")
el.classes:insert("unnumbered")
return el
end
end
However, the HTML portion of the filter does not appear to be working as intended. For the HTML output, I'd like to tuck content under these headings away unnumbered in the appendix, e.g. by adding the classes "appendix" and "unnumbered". Neither of these classes currently appear to be added when running this filter.
I tried adding the classes in the md input and it works as expected, with the heading appearing in the appendix unnumbered:
# Heading {.backmatter .unnumbered .appendix}
Sample text
Running pandoc native, this appears as:
Header
3
( "heading" , [ "backmatter" , "unnumbered" , "appendix" ] , [] )
[ Str "Heading" ]
With only {.backmatter} as an input class and running the filter, it appears as:
Header
3
( "heading" , [ "backmatter" ] , [] )
[ Str "Heading" ]
I've read somewhere about a change in handling of Pandoc for section classes: am I missing something here?

Related

Commands Not Showing in Command Palette with RegReplace (Sublime Text 3)

I'm trying to run a series of commands with the RegReplace plugin in Sublime Text 3 but I cannot get the command to load and I cannot get the keybindings to work either. I have no clue what's wrong.
Steps Taken:
Installed RegReplace
Opened the Command Palette
Searched for "RegReplace: Create New Regular Expression"
Modified the Rule to the following
"""
If you don't need a setting, just leave it as None.
When the rule is parsed, the default will be used.
Each variable is evaluated separately, so you cannot substitute variables in other variables.
"""
# name (str): Rule name. Required.
name = "extract_variables"
# find (str): Regular expression pattern or literal string.
# Use (?i) for case insensitive. Use (?s) for dotall.
# See https://docs.python.org/3.4/library/re.html for more info on regex flags.
# Required unless "scope" is defined.
find = r".*\[(.*[^(<|>)]*?)\].*"
# replace (str - default=r'\g<0>'): Replace pattern.
replace = r"\1"
# literal (bool - default=False): Preform a non-regex, literal search and replace.
literal = None
# literal_ignorecase (bool - default=False): Ignore case when "literal" is true.
literal_ignorecase = None
# scope (str): Scope to search for and to apply optional regex to.
# Required unless "find" is defined.
scope = None
# scope_filter ([str] - default=[]): An array of scope qualifiers for the match.
# Only used when "scope" is not defined.
#
# - Any instance of scope qualifies match: scope.name
# - Entire match of scope qualifies match: !scope.name
# - Any instance of scope disqualifies match: -scope.name
# - Entire match of scope disqualifies match: -!scope.name
scope_filter = None
# greedy (bool - default=True): Apply action to all instances (find all).
# Used when "find" is defined.
greedy = None
# greedy_scope (bool - default=True): Find all the scopes specified by "scope."
greedy_scope = None
# format_replace (bool - default=False): Use format string style replace templates.
# Works only for Regex (with and without Backrefs) and Re (with Backrefs).
# See http://facelessuser.github.io/backrefs/#format-replacements for more info.
format_replace = None
# selection_inputs (bool -default=False): Use selection for inputs into find pattern.
# Global setting "selection_only" must be disabled for this to work.
selection_inputs = None
# multi_pass (bool - default=False): Perform multiple sweeps on the scope region to find
# and replace all instances of the regex when regex cannot be formatted to find
# all instances. Since a replace can change a scope, this can be useful.
multi_pass = None
# plugin (str): Define replace plugin for more advanced replace logic.
plugin = None
# args (dict): Arguments for 'plugin'.
args = None
# ----------------------------------------------------------------------------------------
# test: Here you can setup a test command. This is not saved and is just used for this session.
# - replacements ([str]): A list of regex rules to sequence together.
# - find_only (bool): Highlight current find results and prompt for action.
# - action (str): Apply the given action (fold|unfold|mark|unmark|select).
# This overrides the default replace action.
# - options (dict): optional parameters for actions (see documentation for more info).
# - key (str): Unique name for highlighted region.
# - scope (str - default="invalid"): Scope name to use as the color.
# - style (str - default="outline"): Highlight style (solid|underline|outline).
# - multi_pass (bool): Repeatedly sweep with sequence to find all instances.
# - no_selection (bool): Overrides the "selection_only" setting and forces no selections.
# - regex_full_file_with_selections (bool): Apply regex search to full file then apply
# action to results under selections.
test = {
"replacements": ["extract_variables"],
"find_only": True,
"action": None,
"options": {},
"multi_pass": False,
"no_selection": False,
"regex_full_file_with_selections": False
}
This code Generates the following in AppData\Roaming\Sublime Text 3\Packages\User\reg_replace_rules.sublime-settings
{
"replacements":
{
"extract_variables":
{
"find": ".*\\[(.*[^(<|>)]*?)\\].*",
"name": "extract_variables",
"replace": "\\1"
}
}
}
And then I created the following command under the same directory with filename Default.sublime-commands
[
{
"caption": "Reg Replace: Extract ERS Variables",
"command": "extract_ers_variables",
"args": {
"replacements": [
"extract_variables"
]
}
}
]
After saving all of this, I still do not see the command in the command palette and it didn't show when I tried to save it as a keymap either.
Any help is much appreciated
Came here with my own troubles and may as well document my dumb mistakes. I know nothing of JSON.
When adding two replacements used together going by the examples at the developer's site, I could not get the command to show up in the Command Palette. I could get a keybinding to work, but it gave error messages that the first replacement could not be found…after having successfully used it. The culprit was a malformed reg_replace_rules.sublime-settings file:
//Wrong
{
"replacements":
{
"rep_one":
//stuff
},
"replacements":
{
"rep_two":
//other stuff
}
}
//Correct
{
"replacements":
{
"rep_one":
//stuff, comma
"rep_two":
//other stuff
}
}
Fixing that cleared up the error message, but the command still would not appear in the Command Palette. The problem there was more bad JSON, this time in Default.sublime-commands.
//Wrong
{
"caption": "My Command",
"command": "reg_replace",
"args": {"replacements": ["rep_one", "rep_two"]}
}
//Correct
[
{
"caption": "My Command",
"command": "reg_replace",
"args": {"replacements": ["rep_one", "rep_two"]}
}
]
This is probably obvious to people who have learned JSON properly and use it regularly, and perhaps one day I will be one of those.
The reason this doesn't work for you is that you have the command wrong in your Default.sublime-commands file. In particular, the command extract_ers_variables does not exist, so the entry for it in the command palette is hidden because selecting it wouldn't do anything. Visually speaking, if this command was in a sublime-menu file, the entry in the menu would appear disabled.
If you select Preferences > Package Settings > RegReplace > Quick Start Guide from the menu and follow through the example that's displayed, note that when it comes to the part about creating the command entry in Default.sublime-commands, it tells you to use reg_replace as the command, and the name of the replacements argument is what tells the command which replacement to do.
As such, your entry should look more like:
[
{
"caption": "Reg Replace: Extract ERS Variables",
"command": "reg_replace",
"args": {
"replacements": [
"extract_variables"
]
}
}
]

Yesod Mform and hamlet

Hi I am new to yesod and following the documentation to make a form. In the documentation the form template was created in .hs file itself. But I have a separate hamlet where I want to customize.
I want to access "fields" in my hamlet file. The expected type of 'generateFormPost' is (xml, Enctype) . Can anybody tell me what I should be returning from 'tableMform extra' . I think it should be in xml format. But I think I should not be using toWidget as in below example of documentation.
tableMform extra = do
fields <- forM lis (\(w,h) -> mopt intField "this is not used" (Just h) )
return (fields) ---I know this line has the type error. Can anybody suggest how to deal with it
{-
--I am referring this code from yesod website to make my form. In this it was using runFormGet, but I want use generateFormPost and moreover it was creating a widget which is used in displaying the website. I don't want to create the widget here but in my hamlet file where the 'fields' is accessed via interpolation.
personForm :: Html -> MForm Handler (FormResult Person, Widget)
personForm extra = do
(nameRes, nameView) <- mreq textField "this is not used" Nothing
(ageRes, ageView) <- mreq intField "neither is this" Nothing
let personRes = Person <$> nameRes <*> ageRes
let widget = do
toWidget
[lucius|
##{fvId ageView} {
width: 3em;
}
|]
[whamlet|
#{extra}
<p>
Hello, my name is #
^{fvInput nameView}
\ and I am #
^{fvInput ageView}
\ years old. #
<input type=submit value="Introduce myself">
|]
return (personRes, widget)
-}
getHomeR :: Handler Html
getHomeR = defaultLayout $ do
-- Generate the form to be displayed
(fields, enctype) <- generateFormPost tableMform
let (fires,fiview) = unzip fields
$(widgetFile "layout")
|]
Please let me know if there is any misunderstanding. I have idea of how to get the form from the way done in the documentation, but I want to use a separate hamlet file, as I want to customize the look of the form.
Thanks
Sai
EDIT:
Sorry, I wasn't clear. I was trying to make a Mform where instead of creating the layout of the form in the ".hs" file , I wanted to give the layout in hamlet file. I have done it through http://pastebin.com/fwpZsKXy . But after doing that I could split it in to two files as I wanted. I have solved those errors. Thanks anyways
I got it. I was not clear of what "tableMform extra" has to return. I know that it has to return something of type [(FormResult a, xml)][1] . But then I was not sure what the type of "forM lis ((w,h) -> mopt intField (fromString w) (Just h) )" -- Line 2 was , So I followed what was done in documentation did it in the way it was done there.(without use of external widget file) .
After doing that I tried to do in the way I wanted to do i.e using a separate hamlet, julius and lucius files. http://pastebin.com/FgGph2CU . It worked !!
In summary I wasn't clear of the 'type' of "forM lis ((w,h) -> mopt intField (fromString w) (Just h) )" . Once I figured that out, it was easy.

mediawiki: is there a way to automatically create redirect pages that redirect to the current page?

My hobby is writing up stuff on a personal wiki site: http://comp-arch.net.
Currently using mediawiki (although I often regret having chosen it, since I need per page access control.)
Often I create pages that define several terms or concepts on the same page. E.g. http://semipublic.comp-arch.net/wiki/Invalidate_before_writing_versus_write_through_is_the_invalidate.
Oftentimes such "A versus B" pages provide the only definitions of A and B. Or at least the only definitions that I have so far gotten around to writing.
Sometimes I will define many more that two topics on the same page.
If I create such an "A vs B" or other paging containing multiple definitions D1, D2, ... DN, I would like to automatically create redirect pages, so that I can say [[A]] or [[B]] or [[D1]] .. [[DN]] in other pages.
At the moment the only way I know of to create such pages is manually. It's hard to keep up.
Furthermore, at the time I create such a page, I would like to provide some page text - typicaly a category.
Here;s another example: variant page names. I often find that I want to create several variants of a page name, all linking to the same place. For example
[[multithreading]],
[[multithreading (MT)]],
[[MT (multithreading)]],
[[MT]]
Please don;t tell me to use piped links. That's NOT what I want!
TWiki has plugins such as
TOPICCREATE automatically create topics or attach files at topic save time
More than that, I remember a twiki plugin, whose name I cannot remember or google up, that included the text of certain subpages within your current opage. You could then edit all of these pages together, and save - and the text would be extracted and distributed as needed. (By the way, if you can remember the name of tghat package, please remind me. It had certain problems, particularly wrt file locking (IIRC it only locked the top file for editing, bot the sub-topics, so you could lose stuff.))
But this last, in combination with parameterized templtes, would be almost everything I need.
Q: does mediawiki have something similar? I can't find it.
I suppose that I can / could should wrote my own robot to perform such actions.
It's possible to do this, although I don't know whether such extensions exist already. If you're not averse to a bit of PHP coding, you could write your own using the ArticleSave and/or ArticleSaveComplete hooks.
Here's an example of an ArticleSaveComplete hook that will create redirects to the page being saved from all section titles on the page:
$wgHooks['ArticleSaveComplete'][] = 'createRedirectsFromSectionTitles';
function createRedirectsFromSectionTitles( &$page, &$user, $text ) {
// do nothing for pages outside the main namespace:
$title = $page->getTitle();
if ( $title->getNamespace() != 0 ) return true;
// extract section titles:
// XXX: this is a very quick and dirty implementation;
// it would be better to call the parser
preg_match_all( '/^(=+)\s*(.*?)\s*\1\s*$/m', $text, $matches );
// create a redirect for each title, unless they exist already:
// (invalid titles and titles outside ns 0 are also skipped)
foreach ( $matches[2] as $section ) {
$nt = Title::newFromText( $section );
if ( !$nt || $nt->getNamespace() != 0 || $nt->exists() ) continue;
$redirPage = WikiPage::factory( $nt );
if ( !$redirPage ) continue; // can't happen; check anyway
// initialize some variables that we can reuse:
if ( !isset( $redirPrefix ) ) {
$redirPrefix = MagicWord::get( 'redirect' )->getSynonym( 0 );
$redirPrefix .= '[[' . $title->getPrefixedText() . '#';
}
if ( !isset( $reason ) ) {
$reason = wfMsgForContent( 'editsummary-auto-redir-to-section' );
}
// create the page (if we can; errors are ignored):
$redirText = $redirPrefix . $section . "]]\n";
$flags = EDIT_NEW | EDIT_MINOR | EDIT_DEFER_UPDATES;
$redirPage->doEdit( $redirText, $reason, $flags, false, $user );
}
return true;
}
Note: Much of this code is based on bits and pieces of the pagemove redirect creating code from Title.php and the double redirect fixer code, as well as the documentation for WikiPage::doEdit(). I have not actually tested this code, but I think it has at least a decent chance of working as is. Note that you'll need to create the MediaWiki:editsummary-auto-redir-to-section page on your wiki to set a meaningful edit summary for the redirect edits.

Show Joomla module only in specific articles?

Is it possible to show modules in Joomla only in a specific article (not per menu item), but in standard module position?
For example somehow get the current article id in a template and insert the modules with according id suffix in the name?
I would advise you not to hardcode things like this in the template. My question is, why don't you want to use a menu item? You can create a hidden menu item for that article and use it, then assign the module to that menu item.
If you still want to do it without using a menu item, a possible workaround would be to use something like "mod_php" (some module that allows you to use php code) and do something more or less like this:
Create the module and assign it to a position that is not used anywhere (you can type whatever you want in the module position)
In your php module, put this code:
$option = JRequest::getVar( 'option', '' );
$view = JRequest::getVar( 'view', '' );
$id = JRequest::getInt( 'id', 0 );
if ( $option == "com_content" && $view == "article" && $id == YOUR_ARTICLE_ID ) {
$module = JModuleHelper::getModule('your_module_type', 'module_title');
if ( ! empty( $module ) ) {
$attribs = array( 'style' => 'xhtml' );
echo JModuleHelper::renderModule( $module, $attribs );
}
}
I'm sorry if the code snippet is not showing properly, but I hope you can read it ok. Just one thing, when you fill in the part saying 'your_module_type', don't include the "mod_" part of the name. For example, if you want to output a module of type "mod_article_list", you should write "article_list" in "your_module_type".
I hope it helps!

passing 2-dimensional array in HTTP Request

I'm trying to design a simple API for a webservice I've written. The problem I'm facing is as follows: a form will present to a user any number of themes. This number will change per database.
The user may pick any number of the themes presented and later on can also assign a number value to them to describe level of relevance.
What I need to do is to be able to pass to the webserivce a 2 dimensional array [themeid: theme value] for each selected theme.
I'm not sure how to do that using HTTP get or POST.
Will appreciate any help!
Why do you need a 2d array? Why not pass a list of pairings back where you use an object to encapsulate a theme id and relevance rating pairing? Here is an example in json:
[
{
"rating": 5,
"themeId": 1
},
{
"rating": 3,
"themeId": 2
}
]
whaley has it right pretty much. You want to use json.
Here is an interactive php session to show you how to do this php->json
php > $root = array();
php > $node = new stdClass();
php > $node->theme = "theme";
php > $node->value = "value";
php > $root[12] = $node;
Here's a print_r of this object, to show you what it looks like in php.
php > print_r($root);
Array
(
[12] => stdClass Object
(
[theme] => theme
[value] => value
)
)
Here's an example of the json output.
php > echo json_encode($root);
{"12":{"theme":"theme","value":"value"}}
In essense, you could push this either POST or GET into your application, and json_decode() it to the object in the first section.