php-markdown
php-markdown copied to clipboard
Add support for classes on paragraphs
Is there a special reason why paragraphs cannot define classes? This would be pretty nice to define layouts, even in markdown.
/cc @kburton Referencing you because just just implemented it for tables, maybe you know your way to easily implement this one as well…
I'm sure a syntax for that could be added, but paragraph classes are pretty easy to define already:
{.some-class .proposed-syntax}
A paragraph of text.
vs
<p class="some-class" markdown="1">
A paragraph of text.
</p>
When you compare the code for tables, the ability to add a class via markdown attributes makes a world of difference:
Some | Basic | Table {.table .table-striped}
-----|-------|------
a | b | c
d | e | f
vs
<table class="table table-striped">
<thead>
<tr>
<th>Some</th>
<th>Basic</th>
<th>Table</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
</tr>
<tr>
<td>d</td>
<td>e</td>
<td>f</td>
</tr>
</tbody>
</table>
I was somewhat forced into adding the table attributes because it proved very difficult for non-technical users to maintain syntactic correctness while creating or editing a table like that.
I've been following requests for classes and id attributes with interest. For some constructs, like headers, it's pretty obvious what the syntax should be. But I've restrained myself from implementing something for paragraphs until I've found a satisfying solution for other constructs, mainly lists, out of fear it'd become conflicting later. I'm a little concerned by attributes attached to lists, list items, and paragraphs all being ambiguous with each other.
For instance, where should you put your attributes and what should it do in the following case?
* list item
* list item {.classA}
{.classB}
{.classC}
I'd tend to think classA
should apply to the paragraph, classB
to the item, and classC
to the list as a whole. But that doesn't look good; Markdown is supposed to be readable so I'd like to keep the gibberish of HTML attributes from interfering with reading the text version.
Maybe the rule should be that the attributes must be before the element it qualifies, but that seems quite worse:
{.classA}
* {.classB}
{.classC} list item
* list item
Here classA
is for the list, classB
for the item, and classC
for the paragraph.
Rather, I think should mix things up and say that lists attributes comes before while item and paragraph attributes after:
{.classA}
* list item {.classB}
{.classC}
* list item {.classD}
{.classE}
The paragraph class should be on the same line as the paragraph, while the item class should be on a separate line... that's for cases where a list item contains block-level content (such as paragraphs). Other cases are easier to disambiguate and can be more lax with whitespace.
I don't look forward to documenting that though.
I think I would go with the "before" rule.
{.lala}
this my my paragraph with the lala class
{.lala}
- Thus list
- will have the
- class lala
Regarding list items, I have some idea, but I don't know if that would break anything:
-{.lala} this li will get the class lala
-{.foo} this one will get the class foo
Also, this concept could be used for DL
s.
@kburton Regarding <p class="some-class" markdown="1">
I tend to agree, still… for me it feels wrong to have HTML inside markdown.
@tobiastom The reason Markdown allows HTML is so you can do everything you can do with HTML without having to reinvent a syntax for every HTML feature. It's perfectly fine to use HTML within Markdown.
The problem I'd like to solve is that sometime you need to give up the Markdown syntax entirely because you need a style hook on something. Adding a class to a list or a table forces you to rewrite the entire thing to HTML, which is quite inconvenient. I'm less concerned about mere paragraphs, usually I wrap them in a <div class="some-class" markdown="1">
.
As for list items, I'd like to have single-line items look like this:
- good banana {.good}
- bad orange {.bad}
- good apple {.good}
- so-so blueberry {.so-so}
Here the class can be put on the side, far from the content itself, making it look like a margin annotation. That's why I'm thinking about putting the attributes at the end. It already works like this for headers, and it'd look good for terms in definition lists too. It just doesn't look as good for block-level content.
It could depend on how strict people are with their text formatting. I've gotten into the habit of chopping my paragraphs into smaller chunks for legibility in the raw Markdown. As long as there's some space to push the ID/class declaration it isn't too distracting.
# A Study In Scarlet
## PART I.
(Being a reprint from the reminiscences of John H. Watson, M.D., late of the Army
Medical Department.)
1. ### Mr. Sherlock Holmes
In the year 1878 I took my degree of Doctor of Medicine of the
University of London, and proceeded to Netley to go through
the course prescribed for surgeons in the army. Having completed
my studies there, I was duly attached to the Fifth Northumberland
Fusiliers as Assistant Surgeon. The regiment was stationed in
India at the time, and before I could join it, the second [...]
The campaign brought honours and promotion to many, but for me
it had nothing but misfortune and disaster. I was removed from my
brigade and attached to the Berkshires, with whom I served at
the fatal battle of Maiwand. There I was struck on the [...] {.randomClass}
2. ### More content
Worn with pain, and weak from the prolonged hardships which
I had undergone, I was removed, with a great train of wounded
sufferers, to the base hospital at Peshawar. Here I rallied, and had
already improved so far as to be able to walk about the [...]
p.s. I tend to agree on the adding classes/IDs to every possible element to be overkill.
I really like the right indent style.
The single line list items with the attributes on the right works for me. I think that trying to add attribute support generically to all elements will risk making documents less readable and make the syntax more difficult to write and understand.
In any case, I think the attributes look better before the block in block level elements rather than after.
It's worth considering how Maruku and especially kramdown go about this:
http://kramdown.gettalong.org/syntax.html#inline-attribute-lists http://maruku.rubyforge.org/proposal.html
I think the right margin style is a good argument for putting the attributes at the end. Attributes for headers follow the header, same thing for images and links. Also, that's what Kramdown and Maruku seems to do in other places (thanks @louquillio for those links), even though the syntax is slightly different (it requires a colon).
Now I need to figure out a way to explain what happens with paragraphs nested in blockquotes, lists and other things and disambiguate which attributes applied on which of those nested elements. Perhaps something inside the attribute braces could do that...
* item
* item {ul#id}
That's just a vague idea. Note that in the above example we need to disambiguate between the p
, the li
and the ul
elements.
The right margin syntax worked for inline elements. The kramdown syntax looks nice for block level elements, it allows an attribute directly before or after the block-level element. There has to be a form of attribute precedence, e.g. inline-element preceding-block following-block. Would that work?
Example:
{.list-class}
- good banana {.good}
- bad orange {.bad}
- good apple {.good}
- so-so blueberry {.so-so}
Testing | Basic | Table
--------|-------|------
a | b | c
{.table-class}
Testing | Basic | Table
--------|-------|------
a | b | c
{.table-class}
A paragraph with text
Something I would like to solve are multi column page layouts. For non-technical users it's hard to wrap stuff in <div class="some-class" markdown="1">
HTML-code. Maybe there's a good way for telling Markdown to generate divs? How about paragraphs with kramdown syntax (attribute in preceding-block or following-block) to generate divs?
Example:
{.column-features-class}
No more databases, comment moderation, or pesky updates.
{.column-features-class}
Markdown (or Textile), Liquid, HTML & CSS go in. Static sites come out.
{.column-features-class}
Categories, pages, posts, and custom layouts are all first-class citizens here.
Just an idea.
I don't know. The approach I've taken is to create a template system, where the user chooses the layout that they want and then is prompted to complete the appropriate number of content blocks (and upload the appropriate number of images). This is a lot easier for the end user to understand than trying to add semantic mark up to blocks.
The image below shows the template selection widget, but new templates can be created dynamically by a user with the appropriate permissions.
I'm seconding this feature request. My users cannot possibly wrap their head around any HTML, and that's why I used markdown in the first place. But without the ability to define basic styles on block-level elements, it becomes almost useless in my particular case.
Right now I style headers as general block contents, which is super hacky in CSS. For instance:
// Markdown:
# Needs styling {.style}
// CSS:
h1[class] // Remove styling
{
font: inherit;
margin: 0;
}
h1.style
{
// My custom styles
}
Please do consider the kramdown syntax. I would have moved to this library already if it was somehow possible to use it in PHP...
I have implemented it in way similar to kramdown
some text paragraphs
{:.some-class .other-class #theid}
I didn't study the code, but quickly find a place to implement it, inside the formParagraphs method. I really needed this feature and maybe someone else is interested on this hack while the library give a final solution.
https://github.com/kanzeon/php-markdown/commits/lib
What about having a "fenced" DIV ?
We simply need similar with the syntaxe used for <code>
blocks...
I suggest
::::::::::::::::::::::::::::::::::{ .myClass #myId} my div ::::::::::::::::::::::::::::::::::
I open an new ticket to debate about that suggestion : #191
I think we don't need fenced elements. I just think we need something that assigns attributes or classes to "the next upcoming element" – whatever that element might be.