I have an Rmd file that renders into html correctly almost all of the time. However, it does not render correctly when pandoc (used in the rendering process) finds 4 spaces in the html and at that point, interprets that I want to render a markdown code snippet instead of html.
I have been told that I can turn off the markdown_in_html_blocks feature by doing something like this:
pandoc -f markdown-markdown_in_html_blocks.
I have tried calling pandoc directly rather than it being called implicitly by
rmarkdown::render()
but couldn't get that syntax to work and being able to specify this option (-markdown_in_html_blocks) directly as I call render() is preferred. Here is the latest of I have tried without success:
Base case: works but HTML output file is malformed / has a code block instead of the data that I want to display in the table.
render("reports/Pacing.Rmd")
Attempted fix: not working
rmdFmt <- rmarkdown_format("-markdown_in_html_blocks")
pandocOpts <- pandoc_options(to = "html", from = rmdFmt)
render("reports/Pacing.Rmd",output_format = "html_document",output_file = NULL, output_dir = NULL, output_options = pandocOpts)
Error message: Error in (function (toc = FALSE, toc_depth = 3, toc_float = FALSE, number_sections = FALSE, :
argument 1 matches multiple formal arguments
I have tried other syntax to express that I want to turn off markdown_in_html_blocks but no luck.
Given the following document test.Rmd...
---
title: Test
output: html_document
---
<table>
<tr>
<td>*one*</td>
<td>[a link](https://google.com)</td>
</tr>
</table>
...you can disable the markdown_in_html_blocks extension via
rmarkdown::render("test.Rmd",
output_options = list(md_extensions = "-markdown_in_html_blocks"))
md_extensions is one of the arguments that can be passed to rmarkdown::html_document (see ?rmarkdown::html_document for other arguments).
That seems to be an open issue, but a simpler way to turn off/on such a feature is to directly update the YAML in Rmd file. This should work in your case:
output:
html_document:
pandoc_args: [
"-f", "markdown-markdown_in_html_blocks"
]
Related
I am trying to show the "sgv" value on a Dashing / Smashing dashboard widget. Ultimately I would also like to show the "direction" value as well. I am running into problems pulling that precise value down which changes every 3 to 5 minutes. I have already been able to mirror the exact string using the following:
require 'net/http'
require 'rest-client'
require 'json'
url = "https://dnarnianbg.herokuapp.com/api/v1/entries/current.json"
response = RestClient.get(url)
JSON.parse(response)
# :first_in sets how long it takes before the job is first run. In this case, it is run immediately
current_nightscout = 0
SCHEDULER.every '5m' do
last_nightscout = current_nightscout
current_nightscout = response
send_event('nightscout', { current: current_nightscout, last: last_nightscout })
end
I have also searched the archives several times. I don't wish to write this to a file like this one shows and the duplicate question has been deleted or moved.
I realize that the JSON.parse(response) is just going to parse out whatever I tell it the response equals, but I don't know how to get that response to equal SGV. Maybe the solution isn't in the RestClient, but that is where I am lost.
Here is the JSON URL: http://dnarnianbg.herokuapp.com/api/v1/entries/current.json
EDIT: The output of that link is something like this:
[{"_id":"5ba295ddb8a1ee0aede71822","sgv":87,"date":1537381813000,"dateString":"2018-09-19T18:30:13.000Z","trend":4,"direction":"Flat","device":"share2","type":"sgv"}]
You need something like response[0]["sgv"] which should return 52 if you end up with many items in the list you will need to iterate over them.
The best thing you can do is to break your problem down into easier parts to debug. As you are having problems accessing some JSON via an API you should make a simple script which only does the function you want in order to test it and see where the problem is.
Here is a short example you can put into a .rb file and run;
#!/usr/bin/ruby
require 'open-uri'
require 'json'
test = JSON.parse(open("https://dnarnianbg.herokuapp.com/api/v1/entries/current.json", :read_timeout => 4).read)
puts test[0]["sgv"]
That should return the value from sgv
I realise that short sweet example may be little use as a learner so here is a more verbose version with some comments;
#!/usr/bin/ruby
require 'open-uri'
require 'json'
# Open the URL and read the result. Time out if this takes longer then 4 sec.
get_data = open("https://dnarnianbg.herokuapp.com/api/v1/entries/current.json", :read_timeout => 4).read
# Parse the response (get_data) to JSON and put in variable output
output = JSON.parse(get_data)
# Put the output to get the 'sgv figure'
p output[0]["sgv"]
It always pays to manually examine the data you get back, in your case the data looks like this (when make pretty)
[
{
"_id": "5ba41a0fb8a1ee0aedf6eb2c",
"sgv": 144,
"date": 1537481109000,
"dateString": "2018-09-20T22:05:09.000Z",
"trend": 4,
"direction": "Flat",
"device": "share2",
"type": "sgv"
}
]
What you actually have is an Array. Your server returns only 1 result, numbered '0' hence you need [0] in your p statement. Once you have accessed the array id then you can simply use the object you need as [sgv]
If your app ever returns more than one record then you will need to change your code to read all of the results and iterate over them in order to get all the values you need.
Here is the final code that made it work
require 'net/http'
require 'json'
require 'rest-client'
# :first_in sets how long it takes before the job is first run. In this case, it is run immediately
current_nightscout = 0
SCHEDULER.every '1m' do
test = JSON.parse(open("https://dnarnianbg.herokuapp.com/api/v1/entries/current.json", :read_timeout => 4).read)
last_nightscout = current_nightscout
current_nightscout = p test[0]["sgv"]
send_event('nightscout', { current: current_nightscout, last: last_nightscout })
end
I can probably eliminate require 'rest-client' since that is no longer being used, but it works right now and that is all that matters.
I need to extract information from HTML files. For most of them, I just need to match a particular DOM element's content or attribute, so I use XPATH expressions like //a[#class="targeturl"]/#href and the command line tool xidel.
In a different batch of files the information I want is in a script, not so readily available:
<html>
<head><!-- ... --></head>
<body>
...
<script>
...
var o = {
"numeric": 1234,
"target": "TARGET",
"urls": "http://example.com",
// Commented pair "strings": "...",
"arrays": [
{
"more": true
}
,
{
"itgoeson": true
}
]
};
</script>
...
</body>
</html>
Note that the object containing the value I want to get is not valid JSON. However, it seems to respect one key-value pair per line.
What can I pass to xidel --xpath "???" to get this TARGET?
I've tried different thing with XPATH functions but I can't get to a solution without piping to other commands (match tells me yes/no, replace works line by line..., etc).
Try to implement below XPath:
substring-before(substring-after(//script, '"target": '), ",")
What can I pass to xidel --xpath "???" to get this TARGET?
Since var o is actually JSON, I suggest you treat it as such:
-e "json(
//script/extract(
.,
'var o = (.+);',
1,'s'
)[.]
)/target"
Extract {"field1": 1234, "target": "TARGET", "morefields": "..."} from the <script> element node (the json covers several lines, so don't forget the 's' regex-flag).
Interpret the output as json by wrapping json( ) around it (or //script/...[.] ! json(.)) and select the target attribute.
[edit]
To remove the comments (beginning with //):
-e "json(
//script/replace(
extract(
.,
'var o = (.+);',
1,'s'
)[.],
'\s+//.+',
''
)
)/target"
Not the most prettiest query, but it works.
[/edit]
Assuming I don't want to or cannot modify the stylesheet or the HTML internally, how can I make xtable interpret a section of a string in R as a html tag rather than a literal? For example, I have:
df <- as.data.frame(c("<b>Foo</b>", "Bar", "Box"), byrow = TRUE)
library(xtable)
print(xtable(df), type = "html", include.rownames = FALSE)
I want "Foo" to be bold. Nevertheless, when xtable creates the table, it prints "<b>Foo</b>" (i.e. it interprets the string literally) rather than "Foo". Is there an option or workaround to custom-defining a tag within a string and ensuring that it is interpreted as a tag?
I'm just going to post up an answer for this question, as, after a bit of fidgeting around, I do have a per-se solution.
df <- as.data.frame(c("<b>Foo</b>", "Bar", "Box"), byrow = TRUE)
library(xtable)
print(xtable(df), type = "html", include.rownames = FALSE,
sanitize.text.function = function(x){x})
This works, but can have unintended consequences, since you are overwriting the default santize.text function and it seems that you cannot specify to apply sanitize.text.function = function(x){x} as a lambda function for a particular part of the table, but have to instead apply it to the whole table. It works for something simple like this... might not work for everything.
I create an HTML file using HTML::Template. The resulting code is a valid XML/HTML (check against a xml validator). But while convert to pdf using PDF::FromHTML a message of "invalid token in xml file" is found.
Trying changing the first declaration line from doctype to xml, or supressing, but nothing works. XML::Simple, PDF:API2, XML::Writer are last version.
Ay idea what is happening?
# create template object and store to verify
shout('s',"create template from $str_filepath") if ($bool_DEBUG);
$str_mytemplate = HTML::Template->new(filename => $str_filepath, case_sensitive => 0, no_includes => 1 );
$str_mytemplate->param(\%strct_toreplace);
$str_filepath = envDir('temp').newID().'.html';
shout('',"template created, storing to : $str_filepath") if ($bool_DEBUG);
if (open(FILE, '>', $str_filepath)) {
print FILE $str_mytemplate->output;
close (FILE);
}
# generate pdf from created file
shout('p',"Creating PDF ") if ($bool_DEBUG);
$pdf_this = PDF::FromHTML->new( encoding => 'utf-8' );
$pdf_this->load_file($str_filepath);
$pdf_this->convert( LineHeight => 10, Landscape => 1, PageSize => 'Letter', );
shout('p',"Display PDF") if ($bool_DEBUG);
print header(-type=>'application/pdf', -charset=>'UTF-8');
print $pdf_this->write_file();
$bool_DEBUG and shout(); are a variable and procedure to set and display messages while debugging mode.
Html code generated via template: http://www.etoxica.com/examplecode.html
Template used: http://www.etoxica.com/exampletemplate.tmpl
Message displayed:
SECTION: Creating PDF
Software error:
not well-formed (invalid token) at line 19, column 13, byte 430 at /usr/local/lib64/perl5/XML/Parser.pm line 187.
at /home/grupo/perl/usr/share/perl5/PDF/FromHTML.pm line 141.
Summary: Found the problem (I guess) ;)
Consider the following lines:
<td>
Some line of data
<br/>
A second line of data
</td>
When try to be read by PDF::FromHTML it will send a message of malformed token in the 5th line, specifically on the slash '/' from </td> tag; BUT, that is not the problem, the problem is created by the <br/> tag inside the <td></td>.
If it is changed to <br> or <br /> no error is found. I don't know if using <br> is a good html practice to xml compability, even is defined as it w3c br semantic.
I am new to R and R markdown. In my R code I used a textOutput so the user can enter a title in a blank field. The title is given to a variable called 'title'. How can I display that in an R markdown script that generates pdf, html, and doc files.
Thanks
SOLUTION:
In my Rmd file I wrote this: r dfdrctitle$title and in my server.R file I used this code to get the value for the textOutput:
drctitle <- as.character(input$drc.title)
dfdrctitle <- data.frame( title = drctitle)
You could accomplish this by parameterizing your rmarkdown report. You pass parameters into the report as a list using an option of rmarkdown::render().
First off, in the yaml header of your rmarkdown document you'd include the title parameter. You can access passed parameters into the report via r params$item which instructs knitr to evaluate that as literal r code. You need to quote it because knitr expects a string as a title in the yaml.
---
title: "`r params$rep_title`"
author: "generic_user"
---
Include other output options that you need as well (document output type, etc.). Now to render your report and pass in the parameter in a list that matches the parameter name.
library(rmarkdown)
render(path_to_my_report.rmd,
output_dir = "path_to_mydir",
output_file = "myreport",
params = list(rep_title = title))
Try this in the title field of your header. I believe that you can do this to output any r variable from a code chunk as text, even in a header.
---
title: `r title`
author: "your_name"
date: "11/18/2016"
output: pdf_document
---
R markdown: Accessing variable from code chunk (variable scope)