I'm looking for cleaner solution, more Slim like, to write tag inside tag, this is what I have so far:
td = "#{p.created_at.to_formatted_s(:long)} <small>(#{time_ago_in_words(p.created_at)} ago)</small>".html_safe
Code above works fine - generate output I want, but doesn't look clean for me. I've tried rewrite it to eRuby
<td><%= p.created_at.to_formatted_s(:long) %> <small><%= time_ago_in_words(p.created_at) %> ago)</small></td>
And then convert it to Slim using Erb2Slim converter
td
= p.created_at.to_formatted_s(:long)
small
= time_ago_in_words(p.created_at)
| ago)
After that it doesn't show small tag and its content, any idea how and what is the best way to write above code in Slim?
Seems like you have a problem with indents (spaces). Try to use the following indents:
td
= p.created_at.to_formatted_s(:long)
|
small
| (
= time_ago_in_words(p.created_at)
| ago)
Note: in 3rd line 2 spaces needed after the pipe
Related
I am using Pandoc to generate a list of publications for my website. I'm using it solely to generate the html with the publications so that I can then paste the raw html in jekyll. This part works fine.
The complications arise when I tty to generate the html so that my name appears boldfaced in all entries. I'm trying to use this solution for that, which works when I apply it to a pure Latex document I am generating. However when I try to apply the same Pandoc, the html is generated without any boldface.
Here's my Pandoc file:
---
bibliography: /home/tomas/Dropbox/cv/makerefen4/selectedpubs.bib
nocite: '#'
linestretch: 1.5
fontsize: 12pt
header-includes: |
\usepackage[
backend=biber,
dashed=false,
style=authoryear-icomp,
natbib=true,
url=false,
doi=true,
eprint=false,
sorting=ydnt, %Year (Descending) Name Title
maxbibnames=99
]{biblatex}
\renewcommand{\mkbibnamegiven}[1]{%
\ifitemannotation{highlight}
{\textbf{#1}}
{#1}}
\renewcommand*{\mkbibnamefamily}[1]{%
\ifitemannotation{highlight}
{\textbf{#1}}
{#1}}
...
And here's the relevant part of my Makefile:
PANDOC_OPTIONS=--columns=80
PANDOC_HTML_OPTIONS=--filter=pandoc-citeproc --csl=els-modified.csl --biblatex
Again: this code generates the references fine. It just doesn't boldface anything as it is supposed to.
Any ideas?
EDIT
Bib entries look like this
#MISC{test,
AUTHOR = {Last1, First1 and Last2, First2 and Last3, First3},
AUTHOR+an = {2=highlight},
}
And versions are
- Biblatex 3.12
- Biber 2.12
You can use a lua filter to modify the AST. The following works for me to get the surname and initials (Smith, J.) highlighted in the references (see here). You can replace pandoc.Strong with pandoc.Underline or pandoc.Emph. Replace Smith and J. with your name/initials, save it as myname.lua and use something like:
pandoc --citeproc --bibliography=mybib.bib --csl.mycsl.csl --lua-filter=myname.lua -o refs.html refs.md
i.e. put the filter last.
local highlight_author_filter = {
Para = function(el)
if el.t == "Para" then
for k,_ in ipairs(el.content) do
if el.content[k].t == "Str" and el.content[k].text == "Smith,"
and el.content[k+1].t == "Space"
and el.content[k+2].t == "Str" and el.content[k+2].text:find("^J.") then
local _,e = el.content[k+2].text:find("^J.")
local rest = el.content[k+2].text:sub(e+1)
el.content[k] = pandoc.Strong { pandoc.Str("Smith, J.") }
el.content[k+1] = pandoc.Str(rest)
table.remove(el.content, k+2)
end
end
end
return el
end
}
function Div (div)
if 'refs' == div.identifier then
return pandoc.walk_block(div, highlight_author_filter)
end
return nil
end
Notes:
The above works if you use an author-date format csl. If you want to use a numeric format csl (e.g. ieee.csl or nature.csl) you will need to substitute Span for Para in the filter, i.e.:
Span = function(el)
if el.t == "Span" then
If you also want to use the multiple-bibliographies lua filter, it should go before the author highlight filter. And 'refs' should be 'refs_biblio1' or 'refs_biblio2' etc, depending on how you have defined them:
function Div (div)
if 'refs' or 'refs_biblio1’ or 'refs_biblio2’ == div.identifier then
For pdf output, you will also need to add -V csl-refs in the pandoc command if you use a numeric format csl.
The filter highlights Smith, J. if formated in this order by the csl. Some csl will use this format for the first author and then switch to J. Smith for the rest, so you will have to adjust the filter accordingly adding an extra if el.content[k].t == "Str”…etc. Converting to .json first will help to check the correct formatting in the AST.
I've stored a string in the database. When I save and retrieve the string and the result I'm getting is as following:
This is my new object
Testing multiple lines
-- Test 1
-- Test 2
-- Test 3
That is what I get from a println command when I call the save and index methods.
But when I show it on screen. It's being shown like:
This is my object Testing multiple lines -- Test 1 -- Test 2 -- Test 3
Already tried to show it like the following:
${adviceInstance.advice?.encodeAsHTML()}
But still the same thing.
Do I need to replace \n to or something like that? Is there any easier way to show it properly?
Common problems have a variety of solutions
1> could be you that you replace \n with <br>
so either in your controller/service or if you like in gsp:
${adviceInstance.advice?.replace('\n','<br>')}
2> display the content in a read-only textarea
<g:textArea name="something" readonly="true">
${adviceInstance.advice}
</g:textArea>
3> Use the <pre> tag
<pre>
${adviceInstance.advice}
</pre>
4> Use css white-space http://www.w3schools.com/cssref/pr_text_white-space.asp:
<div class="space">
</div>
//css code:
.space {
white-space:pre
}
Also make a note if you have a strict configuration for the storage of such fields that when you submit it via a form, there are additional elements I didn't delve into what it actually was, it may have actually be the return carriages or \r, anyhow explained in comments below. About the good rule to set a setter that trims the element each time it is received. i.e.:
Class Advice {
String advice
static constraints = {
advice(nullable:false, minSize:1, maxSize:255)
}
/*
* In this scenario with a a maxSize value, ensure you
* set your own setter to trim any hidden \r
* that may be posted back as part of the form request
* by end user. Trust me I got to know the hard way.
*/
void setAdvice(String adv) {
advice=adv.trim()
}
}
${raw(adviceInstance.advice?.encodeAsHTML().replace("\n", "<br>"))}
This is how i solve the problem.
Firstly make sure the string contains \n to denote line break.
For example :
String test = "This is first line. \n This is second line";
Then in gsp page use:
${raw(test?.replace("\n", "<br>"))}
The output will be as:
This is first line.
This is second line.
I am learning grails using the definitive guide to grails 2 (using grails 2.3.7), and when I'm looking at the custom tag library it gives an example custom tag as follows:
def repeat = { attrs, body ->
int n = attrs.int('times)
n?.times { counter ->
out << body(counter +1)
}
}
so when I use this tag like so:
<g:repeat times="3">
Hello number ${it}<br>
</g:repeat>
I expect to get three separate lines on my rendered HTML:
Hello number 1
Hello number 2
Hello number 3
Instead I get:
hello number 1<br>hello number 2<br>hello number 3<br>
I have found methods that look like they should help, like decodeHTML() however I am thus unable to change the output that I want, and I'm not sure what I'm doing wrong.
I have tried doing:
out <<body.decodeHTML()
but I get a null pointer error...
That does not make sense unless there is something else in your taglib or something unusual in the GSP which is invoking the tag.
Does your taglib maybe have something like defaultEncodeAs='html' in it?
Use the tag like this:
<g:repeat times="3">
Hello number ${it}<br/>
</g:repeat>
HTML5 can render <br>, but it seems you are using version 4 or lower.
I have a Rails site, where the content is written in markdown. I wish to display a snippet of each, with a "Read more.." link.
How do I go about this? Simple truncating the raw text will not work, for example..
>> "This is an [example](http://example.com)"[0..25]
=> "This is an [example](http:"
Ideally I want to allow the author to (optionally) insert a marker to specify what to use as the "snippet", if not it would take 250 words, and append "..." - for example..
This article is an example of something or other.
This segment will be used as the snippet on the index page.
^^^^^^^^^^^^^^^
This text will be visible once clicking the "Read more.." link
The marker could be thought of like an EOF marker (which can be ignored when displaying the full document)
I am using maruku for the Markdown processing (RedCloth is very biased towards Textile, BlueCloth is extremely buggy, and I wanted a native-Ruby parser which ruled out peg-markdown and RDiscount)
Alternatively (since the Markdown is translated to HTML anyway) truncating the HTML correctly would be an option - although it would be preferable to not markdown() the entire document, just to get the first few lines.
So, the options I can think of are (in order of preference)..
Add a "truncate" option to the maruku parser, which will only parse the first x words, or till the "excerpt" marker.
Write/find a parser-agnostic Markdown truncate'r
Write/find an intelligent HTML truncating function
Write/find an intelligent HTML truncating function
The following from http://mikeburnscoder.wordpress.com/2006/11/11/truncating-html-in-ruby/, with some modifications will correctly truncate HTML, and easily allow appending a string before the closing tags.
>> puts "<p><b>Something</p>".truncate_html(5, at_end = "...")
=> <p><b>Someth...</b></p>
The modified code:
require 'rexml/parsers/pullparser'
class String
def truncate_html(len = 30, at_end = nil)
p = REXML::Parsers::PullParser.new(self)
tags = []
new_len = len
results = ''
while p.has_next? && new_len > 0
p_e = p.pull
case p_e.event_type
when :start_element
tags.push p_e[0]
results << "<#{tags.last}#{attrs_to_s(p_e[1])}>"
when :end_element
results << "</#{tags.pop}>"
when :text
results << p_e[0][0..new_len]
new_len -= p_e[0].length
else
results << "<!-- #{p_e.inspect} -->"
end
end
if at_end
results << "..."
end
tags.reverse.each do |tag|
results << "</#{tag}>"
end
results
end
private
def attrs_to_s(attrs)
if attrs.empty?
''
else
' ' + attrs.to_a.map { |attr| %{#{attr[0]}="#{attr[1]}"} }.join(' ')
end
end
end
Here's a solution that works for me with Textile.
Convert it to HTML
Truncate it.
Remove any HTML tags that got cut in half with
html_string.gsub(/<[^>]*$/, "")
Then, uses Hpricot to clean it up and close unclosed tags
html_string = Hpricot( html_string ).to_s
I do this in a helper, and with caching there's no performance issue.
You could use a regular expression to find a line consisting of nothing but "^" characters:
markdown_string = <<-eos
This article is an example of something or other.
This segment will be used as the snippet on the index page.
^^^^^^^^^^^^^^^
This text will be visible once clicking the "Read more.." link
eos
preview = markdown_string[0...(markdown_string =~ /^\^+$/)]
puts preview
Rather than trying to truncate the text, why not have 2 input boxes, one for the "opening blurb" and one for the main "guts". That way your authors will know exactly what is being show when without having to rely on some sort of funkly EOF marker.
I will have to agree with the "two inputs" approach, and the content writer would need not to worry, since you can modify the background logic to mix the two inputs in one when showing the full content.
full_content = input1 + input2 // perhaps with some complementary html, for a better formatting
Not sure if it applies to this case, but adding the solution below for the sake of completeness. You can use strip_tags method if you are truncating Markdown-rendered contents:
truncate(strip_tags(markdown(article.contents)), length: 50)
Sourced from:
http://devblog.boonecommunitynetwork.com/rails-and-markdown/
A simpler option that just works:
truncate(markdown(item.description), length: 100, escape: false)
I'm just starting to pick up ASP.Net MVC and find myself writing a lot of <%= %> in the views. Intellisense does supply the closing %>, but I find that typing the introductory <%= to be burdensome (they are tough for me to type :-)).
I've dabbled around a bit with Rails and the NetBeans IDE where I was able to type:
r<tab> - which would expand to <% %>
and
re<tab> - which would expand to <%= %>
Can something similar be done in the Visual Studio 2008 IDE?
Based on a comment, I double-checked the snippets answer below and it unfortunately doesn't run in HTML view. The other way to do this is via a recorded macro:
In your web project, start recording: CTRL+SHIFT+R
Type <%= %> then return the caret to between the spaces after the "="
Stop recording: CTRL+SHIFT+R
Insert the macro via CTRL+SHIFT+P
That could be enough, but it would be better to have it across all projects, plus we'd like a better keystroke than CTRL+SHIFT+P:
Save the Macro: Tools->Macros->Save Temporary Macro, giving it a name
Bind it to a keystroke combination:
Tools->Options, and choose the Keyboard node
Search for the name you chose
Enter a key combination (e.g. ALT+A) and click OK
Now you can press the key shortcut (e.g. ALT+A) in HTML view, it will insert <%= %>, and position the caret in the tags, ready for input.
[Old Answer: doesn't work in HTML view, unfortunately.]
For a Code Snippet, create an XML snippet file (e.g. "asp.snippet") with the name, shortcut and expansion, then use Tools -> Code Snippet Manager to add the folder where your snippet is stored.
Here's the XML for snippet that (via "asp[tab][tab]"), expands "<%= [code] %>"
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
<Header>
<Title>ASP Server Tags</Title>
<Author>Chris Bowen</Author>
<Shortcut>asp</Shortcut>
<Description>ASP.NET server escape characters, including equals</Description>
<SnippetTypes>
<SnippetType>SurroundsWith</SnippetType>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Declarations>
<Literal>
<ID>code</ID>
<Default>Code</Default>
</Literal>
</Declarations>
<Code Language="csharp">
<![CDATA[<%= $code$ $selected$%>$end$]]>
</Code>
</Snippet>
</CodeSnippet>
More details are here on MSDN.
BTW, VS has a snippet to create snippets. Just open a new XML file, then right click and choose Insert Snippet -> "Snippet".
This macro function should do it:
The main code will do one of two things, if nothing is selected it will just insert the <%= %> code construct, if you have something currently selected in the editor, it will wrap that code with the construct E.G. <%= selected code here %>
Public Sub WrapMVC()
Try
DTE.UndoContext.Open("Wrap MVC")
Dim OutText As String = ""
Dim OutFormat As String = "<%={0} %>"
DTE.ActiveDocument.Selection.Text = String.Format(OutFormat, ActiveWindowSelection)
Finally
DTE.UndoContext.Close()
End Try
End Sub
Helper Routines:
Friend Function ActiveWindowSelection() As String
If DTE.ActiveWindow.ObjectKind = EnvDTE.Constants.vsWindowKindOutput Then
Return OutputWindowSelection()
End If
If DTE.ActiveWindow.ObjectKind = "{57312C73-6202-49E9-B1E1-40EA1A6DC1F6}" Then
Return HTMLEditorSelection()
End If
Return SelectionText(DTE.ActiveWindow.Selection)
End Function
Private Function HTMLEditorSelection() As String
Dim hw As EnvDTE.HTMLWindow = ActiveDocument.ActiveWindow.Object
Dim tw As TextWindow = hw.CurrentTabObject
Return SelectionText(tw.Selection)
End Function
Private Function OutputWindowSelection() As String
Dim w As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
Dim ow As OutputWindow = w.Object
Dim owp As OutputWindowPane = ow.OutputWindowPanes.Item(ow.ActivePane.Name)
Return SelectionText(owp.TextDocument.Selection)
End Function
Private Function SelectionText(ByVal sel As EnvDTE.TextSelection) As String
If sel Is Nothing Then
Return ""
End If
If sel.Text.Length <= 2 Then
SelectWord(sel)
End If
If sel.Text.Length <= 2 Then
Return ""
End If
Return sel.Text
End Function
Private Sub SelectWord(ByVal sel As EnvDTE.TextSelection)
Dim leftPos As Integer
Dim line As Integer
Dim pt As EnvDTE.EditPoint = sel.ActivePoint.CreateEditPoint()
sel.WordLeft(True, 1)
line = sel.TextRanges.Item(1).StartPoint.Line
leftPos = sel.TextRanges.Item(1).StartPoint.LineCharOffset
pt.MoveToLineAndOffset(line, leftPos)
sel.MoveToPoint(pt)
sel.WordRight(True, 1)
End Sub
I believe Code Snippets would fit the bill.
I've found it straight forward to write a macro and then bind it to a keyboard command.
I use Tools->Macros->Macro Explorer to see what's there and you can create a new module and add in a macro to inject your code. Then you bind it to a key with Tools->Customize->Keyboard...
Since it's not too different from what you're doing, here is a macro to inject a source command with the date and username - VBScript - I didn't look to hard for other alternatives.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Public Module Module1
Private Function GetUserName() As String
GetUserName = System.Environment.UserName
End Function
Sub InjectChangeComment()
ActiveDocument().Selection().Text = "// " + System.DateTime.Now.ToString("MM-dd-yy") + " " + GetUserName() + vbTab + vbTab + vbTab
End Sub
End Module
Code Snippets in the HTML view do not work. It's slated for the next version of Visual Studio. I'd look at a Macro approach for now, or see if other tools allow for snippets in the HTML editor.
One good tool which will allow you to do this is Resharper. You can create your own templates that will do what you require but also have surround with tags too. There are a whole host of features and is well worth it for the price.