I don't undestand how to create a new line using Markdown Redcarpet.
I type
Line 1
Line 2
But I see
Line 1 Line 2
In my helper I have markdown = Redcarpet::Markdown.new(MarkdownRenderer, hard_wrap: true, autolink: true, space_after_headers: true)
According to the Redcarpet manual, the auto_wrap option goes into the Renderer initializer like this:
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(hard_wrap: true), autolink: true, space_after_headers: true)
puts markdown.render("Line 1\n Line 2")
which gives me this output
<p>Line 1<br>
Line 2</p>
https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch
Please note that I couldn't find a MarkdownRenderer class as Redcarpet comes only with a Redcarpet::Render::HTML and Redcarpet::Render::XHTML built in renderer.
Related
I've been working on creating a YAML re-formatter based on ruamel.yaml (which you can see here).
I'm currently using version 0.17.20.
Cleaning up comments and whitespace has been difficult. I want to:
ensure there is only one space before the # for EOL comments
align full line comments with the key or item immediately following
remove duplicate blank lines so there is at most one blank line
To get closer to achieving that, I have a custom Emitter class where I extend write_comment to adjust the comments just before writing with super().write_comment(...). However, the Emitter does not know about which key or item comes next because comments are generally attached as post comments.
As I've studied the ruamel.yaml code to figure out how to do this, I found the rtsc mode (Round Trip Split Comments) which looks fantastic because it separates EOLComment, BlankLineComment and FullLineComment instead of lumping them together.
From what I can tell, the Parser and Scanner have been adjusted to capture the comments. So, loading is (mostly?) implemented with this "NEWCMNT" implementation. But Emitter.write_comment expects CommentToken instead of comment line numbers, so dumping does not work yet.
If I update my Emitter.write_comment method, is that enough to finish dumping? Or what else might be necessary? In one of my tries, I ran into a sys.exit in ScannedComments.assign_eol() - what else is needed to finish that?
PS: I wouldn't normally ask how to collaborate on StackOverflow, but this is not a bug report or a feature request, and I'm trying/failing to use a new (undocumented) feature, so I'm filing this here instead of sourceforge.
rtsc is work in progress cq work started but unfinished. It's internals will almost certainly change.
Two of the three points you indicate can relatively easy be implemented:
set the column of each comment to 0 ( by recursively going over a loaded data structure similar to here ) if the column is before the position of the end of the value on a line, you'll get one space between the value and the column
at the same time doing the recursion in the previous point. Take each comment value and do something like:
value = '\n'.join(line.strip() for line in value.splitlines()
while '\n\n\n' in value:
value = value.replace('\n\n\n', '\n\n')
The indentation to the following element is difficult, depends on the
data structure etc. Given that these are full line comments, I suggest
you do some postprocessing of the YAML document you generate:
find a full line comment, gather full line comments until next line is
not full line comment (i.e. some "real" YAML). Since full line comments
are in column[0] if the previous stuff is applied, you don't have to
track if you are in a (multi-line) literal or folded scalar string where
one of the lines happens to start with #
determine number of spaces
before real YAML and apply these to the full line comments.
import sys
import ruamel.yaml
yaml_str = """\
# the following is a example YAML doc
a:
- b: 42
# collapse multiple empty lines
c: |
# this is not a comment
it is the first line of a block style literal scalar
processing this gobbles a newline which doesn't go into a comment
# that is unless you have a (dedented) comment directly following
d: 42 # and some non-full line comment
e: # another one
# and some more comments to align
f: glitter in the dark near the Tannhäuser gate
"""
def redo_comments(d):
def do_one(comment):
if not comment:
return
comment.column = 0
value = '\n'.join(line.strip() for line in comment.value.splitlines()) + '\n'
while '\n\n\n' in value:
value = value.replace('\n\n\n', '\n\n')
comment.value = value
def do_values(v):
for x in v:
for comment in x:
do_one(comment)
def do_loc(v):
if v is None:
return
do_one(v[0])
if not v[1]:
return
for comment in v[1]:
do_one(comment)
if isinstance(d, dict):
do_loc(d.ca.comment)
do_values(d.ca.items.values())
for val in d.values():
redo_comments(val)
elif isinstance(d, list):
do_values(d.ca.items.values())
for elem in d:
redo_comments(elem)
def realign_full_line_comments(s):
res = []
buf = []
for line in s.splitlines(True):
if not buf:
if line and line[0] == '#':
buf.append(line)
else:
res.append(line)
else:
if line[0] in '#\n':
buf.append(line)
else:
# YAML line, determine indent
count = 0
while line[count] == ' ':
count += 1
if count > len(line):
break # superfluous?
indent = ' ' * count
for cline in buf:
if cline[0] == '\n': # empty
res.append(cline)
else:
res.append(indent + cline)
buf = []
res.append(line)
return ''.join(res)
yaml = ruamel.yaml.YAML()
# yaml.indent(mapping=4, sequence=4, offset=2)
# yaml.preserve_quotes = True
data = yaml.load(yaml_str)
redo_comments(data)
yaml.dump(data, sys.stdout, transform=realign_full_line_comments)
which gives:
# the following is a example YAML doc
a:
- b: 42
# collapse multiple empty lines
c: |
# this is not a comment
it is the first line of a block style literal scalar
processing this gobbles a newline which doesn't go into a comment
# that is unless you have a (dedented) comment directly following
d: 42 # and some non-full line comment
e: # another one
# and some more comments to align
f: glitter in the dark near the Tannhäuser gate
I don't quite understand placement of chunks in an Rstudio notebook. I need to know how to make the chunks and results in the markdown appear in the same order as the original document and be able to control which are included using the include= chunk option.
---
title: "Test markdown"
output:
html_notebook: default
---
```{r, setup, include=FALSE}
# set default chunk options:w
knitr::opts_chunk$set(echo = FALSE, include = FALSE, fig.width = 8, collapse = TRUE, warning = FALSE)
```
Note 0
```{r}
# Comment
c <- 92461110
m <- 7056556
```
```{r, include=TRUE}
c
```
Note 1
```{r}
paste("Nothing")
```
Note 2
```{r,include=TRUE}
paste("Something")
```
```{r, include=TRUE}
paste("something else")
```
I should get
Test Markdown
Note 0
92461110
Note 1
Note 2
[1] "Something"
[1] "Something else"
Instead I get
Test markdown
Note 0
Note 1
Note 2
[1] "Nothing"
[1] "Something"
When the rmarkdown file is knitted, there are something after the title area, as it is shown in the picture.
How to remove those?
I have set "warning=FALSE, comment=NA" in the r code chunk, but it does not work.
Some of the codes are as follows:
---
title: 'Validness Report by All Facilities'
subtitle: '2017-01-03 to 2017-01-09'
output: pdf_document
geometry: margin=0.5in
classoption: landscape
documentclass: article
---
```{r input, echo = FALSE, results = 'hide', cache = TRUE,
warning=FALSE, comment=FALSE, error=FALSE}
setwd("F:/")
dfDataIn_valid2 <- read.csv("full_valid.csv", stringsAsFactors = FALSE)
```
```{r validness, echo = FALSE, results = 'hide',
cache = TRUE, warning=FALSE, comment=FALSE, error=FALSE}
# Check if required packages are installed. If not, install them.
packages <- c("rJava", "xlsxjars", "xlsx", "lubridate", "dplyr", "lazyeval")
lapply(packages, library, character.only = TRUE)
```
You need chunk option message set to FALSE
```{r, echo = FALSE, results = 'hide', cache = TRUE, warning=FALSE, comment=FALSE, error=FALSE, message=FALSE)}
Also, you don't need to repeat the options for each chunk; you could also just set them in the first one:
```{r}
library(knitr)
opts_chunk$set(echo = FALSE, results = 'hide', cache = TRUE, warning=FALSE, comment=FALSE, error=FALSE, message=FALSE)
```
I added this block to my deck.rb:
text(str: 'Gain 1 :tribute:') do |embed|
embed.svg key: ':tribute:', file: 'tribute.svg'
end
However, this puts "Gain 1 [my icon here]" into the top left of every card, but not where the card text says "Gain 1 tribute."
If I add this line, in an attempt to make it specify the "Ability" column in my .csv file:
%w(Ability).each do |key|
Then I get an error message:
"Syntax error, unexpected end-of-input, expecting keyword_end."
What do I need to add to my deck.rb, exactly, in order to make it use the tribute.svg icon wherever cards within the Ability column have the text, "Gain 1 tribute"?
Here's my current deck.rb:
require 'squib'
require 'game_icons'
Squib::Deck.new(cards: 4, layout: %w(hand.yml layout.yml)) do
background color: '#FFFFFF'
data = csv file: 'country.csv'
png file: data['Art'], layout: 'Art'
%w(Title Ability Quote Type Subtype).each do |key|
text str: data[key], layout: key, markup: true
end
%w(Tribute Power Dominion).each do |key|
svg file: "#{key.downcase}.svg", layout: "#{key}Icon"
text str: data[key], layout: key
end
text(str: 'Gain 1 :tribute:', x: 275, y: 745) do |embed|
embed.svg key: ':tribute:', file: 'tribute.svg'
end
save_png prefix: 'country_'
end
The text method needs to have x and y specified. Like this:
text(str: 'Gain 1 :tribute:', x: 300, y: 500) do |embed|
embed.svg key: ':tribute:', file: 'tribute.svg'
end
As for the syntax error, every do needs an end, because you're defining a block. Although that part seems unrelated to the first part of your question. The snipped %w(Ability).each seems silly to me because that's just iterating over a 1-element array.
To get the image dimensions in ruby, I tried to use identify to get image dimensions. I wanted to retrieve the output of this system call and get the output as a string
str = system('identify -format "%[fx:w]x%[fx:h]" image.png')
output = `ls`
print output
But, I'm getting the last lines of output and not the output to this particular system call.
Also, if there is a simpler way to get the image dimensions without external gems or libraries, please suggest as it would be great !
Since you already use an external library (ImageMagick), you could use its Ruby wrapper RMagick:
require 'RMagick'
img = Magick::Image::read('image.png').first
arr = [img.columns, img.rows]
Here's an example of a very simple PNG parser:
data = File.binread('image.png', 100) # read first 100 bytes
if data[0, 8] == [137, 80, 78, 71, 13, 10, 26, 10].pack("C*")
# file has a PNG file signature, let's get the image header chunk
length, chunk_type = data[8, 8].unpack("l>a4")
raise "unknown format, expecting image header" unless chunk_type == "IHDR"
chunk_data = data[16, length].unpack("l>l>CCCCC")
width = chunk_data[0]
height = chunk_data[1]
bit_depth = chunk_data[2]
color_type = chunk_data[3]
compression_method = chunk_data[4]
filter_method = chunk_data[5]
interlace_method = chunk_data[6]
puts "image size: #{width}x#{height}"
else
# handle other formats
end
Okay, I finally found a solution after some experiments.
str = `identify -format "%[fx:w]x%[fx:h]" image.png`
arr = str.split('x')
The array arr now contains dimensions in it [width,height] .
This worked for me ! Please suggest other approaches that might be more easier or simpler.