How to I have several haml lines appear on the same line? - ruby

I have the following haml:
9 %strong Asked by:
10 = link_to #user.full_name, user_path(#user)
11 .small= "(#{#question.created_at.strftime("%B %d, %Y")})"
This currently puts the link and the date on separate lines, when it should look like "link (date)" and date has a class span of small.....

Your code will generate something like this html:
<strong>Asked by:</strong>
User name
<div class='small'>April 26, 2011</div>
When you use something like .small (i.e. use the dot without specifying the element type) haml creates an implicit div. Since div elements are by default block level elements the date will be in a new block and so will appear on a new line. In order to get it to appear on the same line, you'll need an inline level element.
You could change the css for the "small" class to explicitly make it display inline, but html already provides an inline version of the div - the span, so you can change the last line from
.small= "(#{#question.created_at.strftime("%B %d, %Y")})"
to
%span.small= "(#{#question.created_at.strftime("%B %d, %Y")})"
which will give you
<strong>Asked by:</strong>
User name
<span class='small'>April 26, 2011</span>
which are all inline elements, so will appear as one line.
As for having it all on the same line in the haml, I don't think that's possible with plain haml syntax. Haml uses the indentation and whitespace in order to determine what to do, and having just one line means there's no indentation.
The haml FAQ says:
Expressing the structure of a document and expressing inline formatting are two very different problems. Haml is mostly designed for structure, so the best way to deal with formatting is to leave it to other languages that are designed for it.
You seem to be at the edge of what haml is intended for. You could write your html directly if you really wanted it all on one line:
<strong>Asked by:</strong> #{link_to #user.full_name, user_path(#user)} <span class="small">(#{#question.created_at.strftime("%B %d, %Y")})</span>
or perhaps you could create a helper that will generate the block for you.

To make it show up on the same line in the browser, use %span.small, as in the comment above.
To make it all on one line in the HTML output, you will need to use the whitespace removal syntax in Haml. Please understand that newlines in the HTML output do not effect the arrangement of text in the browser.

Related

Why is my Ruby lookahead regex not working [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
RegEx match open tags except XHTML self-contained tags
I tested my regex in rubular.com and it works, but when I run the code it behaves differently.
I want to parse whole paragraphs out of some HTML code
Here is my regex
description = ad_page.body.scan(/(?<=<span id="preview-local-desc">).+(?=<\/span>)/m)
Here is some of the HTML source
<span id="preview-local-desc"> I want to pick up everything typed here.
Paragraphs, everything.
</span>
The match begins where I need it to but then it keeps matching all the way to the end of the document.
Aside from the fact that you shouldn't parse HTML with regex, you want non-greedy matching:
/(?<=<span id="preview-local-desc">).+?(?=<\/span>)/m
Parsing XML or HTML with a regex is marginally OK for trivial tasks, if you own or control the file's format. If you don't, then a simple change to the file could break your regex.
Using a parser will avoid that problem; I've parsed some horrible XML with Nokogiri and it didn't even notice. After writing a RSS aggregator that was handling 1000+ feeds I was hooked on using a parser.
require 'nokogiri'
html = '<span id="preview-local-desc"> I want to pick up everything typed here.
Paragraphs, everything.
</span>'
doc = Nokogiri.HTML(html)
doc.at('span').text
# => " I want to pick up everything typed here.\n Paragraphs, everything.\n "
If there are multiple <span> tags you want:
doc.search('span').map(&:text)
# => [" I want to pick up everything typed here.\n Paragraphs, everything.\n "]
If there are multiple <span> tags and you only want this one:
doc.at('span#preview-local-desc').text
# => " I want to pick up everything typed here.\n Paragraphs, everything.\n "

Pep8 Python3.3 Contradiction

Pep 8 has the following rules
Blank Lines
Separate top-level function and class definitions with two blank
lines.
Method definitions inside a class are separated by a single blank
line.
Extra blank lines may be used (sparingly) to separate groups of
related functions. Blank lines may be omitted between a bunch of
related one-liners (e.g. a set of dummy implementations).
Use blank lines in functions, sparingly, to indicate logical sections.
Python accepts the control-L (i.e. ^L) form feed character as
whitespace; Many tools treat these characters as page separators, so
you may use them to separate pages of related sections of your file.
Note, some editors and web-based code viewers may not recognize
control-L as a form feed and will show another glyph in its place.
However, you can't have a completely blank line inside a class defintion
Example from my head:
class bunny:
def spam(self):
pass
def eggs(self):
pass
#a second example
class bunny2:
def __init__(self):
self._eggs = None
def eggs(self):
doc = "Spam and Eggs"
def fget(self, value):
return self._eggs
def fset(self, value):
self._eggs = value
def fdel(self):
del self._eggs
return locals()
eggs = property(**eggs())
The line between spam and eggs needs to be a blank line, however, that will result in a parse error of unexpected indentation. Is there another character that should go in that space? My assumption is just leave the spaces/tabs on the "blank" line because it is more readable.
In the second example nested defs need to have their previous lines indention maintained for the parse to work correctly.
What is the correct PEP 8 way to handle this? Blank line, blank line with white space, no line?
If you're working in the REPL, you can't have entirely blank lines. But there is no reason for code entered in the REPL to strictly adhere to PEP 8, anyway. But inside a file, it is a good idea to follow PEP 8.

Using an "uncommon" delimiter for creating arrays in Ruby on Rails

I am building an app in Ruby on Rails in which I am pulling in content another file, and wonder if there's any simple way to create a unique delimiter for separating string content, or whether there's another approach I should take.
Let's say I have a paragraph of text, I'd like to pull in, and let's say I don't know what the text will contain.
What I would like to do is put some sort of delimiter at, let's say, 5 random points in the paragraph so that, later on, an array can be created in which content up to that delimiter can be separated out into an individual element.
For a bit of context, let's say I have a paragraph pulled in as a string:
Hello, this is a paragraph of text which will be delimited. Goodbye.
Now, let's say I add a delimiter at various points, as follows (I know how to do this in code):
Hello, this [DELIMITER] is a paragraph [DELIMITER] of text which [DELIMITER] will [DELIMITER] be delimitted. Goodbye.
Again, I know how to do this, but let's say I'm able to use the above to create an array as follows:
my_array = ["Hello, this", "is a paragraph", "of text which", "will", "be delimitted. Goodbye"
I'm confident of achieving all of the above. The challenge I'm having is: what should my delimiter be?
Normally, commas are used as delimiters but, if the text already includes a comma, this will result in delimitations where I do not wish them to occur. In the above example, for example, the comma between "Hello" and "this" would cause the "Hello, this" element to be split up into "Hello" and "this"—not what I want.
What I have thought of doing is using a random (hex) number generator to create a new delimiter each time the page is loaded, e.g. "Hello, this 023ABCDEF is a paragraph 023ABCDEF...", but I'm not sure this is the correct approach.
Is there a simpler solution?
Multipart mime messages take (more or less) the approach of a GUID separator; it's adequate.
I view this as a different type of problem, though, closer to a text editor marking sections of text bold, or italic, etc. That can be handled via string parsing (a la Markdown, SO's formatting) or data structures.
The text editor approach is generally more flexible, and instead of a simple collection of strings, uses a collection (or tree) of structures that hold metadata about the section (type, formatting, whatever).
The best approach depends on your needs:
Are sections nestable?
Will this be rendered?
If so, do section "types" need specific rendering?
Are there section "types", or are they all the same?
Will the text in question be edited before, during, or after sectioning?
Etc.

xml tag with a dot in haml

I have a tag that contains a dot (.) that I want haml to preserve:
Haml:
%text
%text.resource
...
I would like Haml to expand to:
<text>
<text.resource>...
</text.resource>
<text>
but it keeps doing:
<text>
<text class="resource">...
<text>
<text>
Is there any easy way to "escape" "class" expansion in Haml?
HAML is made to generate HTML of various forms, but you can trick it to generate other things by being creative. Putting in what you want to get back out:
<text>
<text.resource>...
</text.resource>
<text>
will work, because if HAML sees a line that doesn't start with one of its reserved characters it'll output it as is. You can't indent though, or it will get mad.
From the docs:
Note that HTML tags are passed through unmodified as well. If you have some HTML you don’t want to convert to Haml, or you’re converting a file line-by-line, you can just include it as-is. For example:
%p
<div id="blah">Blah!</div>
is compiled to:
<p>
<div id="blah">Blah!</div>
</p>
You could do:
<text>
= " <text.resource>..."
= " </text.resource>"
<text>
if you insist on indentation:
>> <text>
>> <text.resource>...
>> </text.resource>
>> <text>
EDIT:
The OP says:
the problem I have is that the elypsis (...) means that I have to add more haml code there (a bunch of xml tags that would be "children" of and therefore I need to "indent" the lines after the comments...
XML doesn't care about indentation; Indentation is a for-human-eyes-only aesthetic. I'd worry more about being functionally and syntactically correct. If you absolutely have to have "pretty" XML, then consider running the HAML output through xmllint, or tidy with the xml flags set.
Or, abandon HAML because you're starting to abuse it, and use something like ERB and/or Erubis which is more free form and less caring about syntax, or go old-school and generate the XML via print and puts statements. If you insist on using HAML and having your indentation, then I'd suggest consulting with the HAML developers and see if they have a recommendation. There might be a HAML filter that would be of use, or some other way of forcing the indentation level inline.
My advice, as someone who's been doing this a long time and been there too many times is: We, as software developers, can lose sight of the end-goal of being functional and spin off into some yak-shaving exercise worrying about minutia that don't accomplish anything real. Unless it's a specification that every indenting space is sacred I'd worry more about getting correct XML and move on, then later return to it and see if it can be tweaked to perfection.

How can I strip whitespace and newlines with Mako templates? My 12362 line HTML file is killing IE

I'm using the Mako template system in my Pylons website and am having some issues with stripping whitespace.
My reasoning for stripping whitespace is the generated HTML file comes out as 12363 lines of code. This, I assume, is why Internet Explorer is hanging when it tries to load it.
I want to be able to have my HTML file look nice and neat so I can make changes to it with ease and have the generated output look as ugly and messy as required to cut down on filesize and memory usage.
The Mako documentation http://www.makotemplates.org/docs/filtering.html says you can use the trim flag but that doesn't seem to work. Example code:
<div id="content">
${next.body() | trim}
</div>
The only way I've been able to strip the newlines is to add a \ (backslash) to the end of each line. This is rather annoying when coding the views and I'd prefer to have a centralized solution.
How do I remove the whitespace/newlines ?
I don't believe IE hanging is due to the file size. You have probably just found a combination of markup that hits an IE bug that causes it to freeze. Try trimming down you document until the freeze no longer happens to isolate the offending piece of markup pattern (and then avoid the markup pattern), or try changing the markup until this no longer happens.
Another good thing to do would be to run your page through HTML validator and fixing any issues reported.
I'm guessing that the trim filter is treating your html as a single string, and only stripping the leading and trailing whitespace characters. You want it to strip whitespace from every line. I would create a filter and iterate over each line.
<%!
def better_trim(html):
clean_html = ''
for line in html:
clean_html += line.strip()
return clean_html
%>
<div id="content">
${next.body() | better_trim}
</div>
You could create your own simple WSGI Middleware to strip whitespace from your templates after they've been rendered (possibly using the methods described in this answer).
Below is a quick example which might help you get started. Note: I wrote this code without testing or even running it; it may work first time, but it probably won't suit your needs so you'll need to expand on this yourself.
class HTMLMinifyMiddleware(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
resp_body = self.app(environ, start_response)
for i, part in enumerate(resp_body):
resp_body[i] = ' '.join(part.split())
return resp_body

Resources