Edgewall Software
Modify

Opened 19 years ago

Closed 16 years ago

#2048 closed enhancement (fixed)

Wiki macros for generating `<div>`s and `<span>`s with classes

Reported by: Christian Boos Owned by: Christian Boos
Priority: high Milestone: 0.11
Component: wiki system Version: devel
Severity: major Keywords: macro wikiprocessor
Cc: dkg-debian.org@… Branch:
Release Notes:
API Changes:
Internal Changes:

Description (last modified by Christian Boos)

My original request was:

I would like to have a wiki notation for highlighting sentences in a page, in a more striking way than just bold or italic.

Typical use cases would be for short words like "FIXME" or "TODO", that should immediately stand out from normal text, so that it would be clear that those are inlined comments to the text itself.

The proposed syntax would be: * TODO *

and would be rendered as: TODO

That particular example will be supported by the th:WikiGoodiesPlugin.

However, this ticket raises the more general concern that Trac core should have a macro that supports generating <div>s and <span>s with classes. This is even more necessary with 0.11, as there, the HTML processor blocks no longer support leaving elements open.

Attachments (4)

2048.patch (1.7 KB ) - added by Christian Boos 19 years ago.
patch against 0.9b1 (or close) for the proposed feature
div-span-macro.patch (2.2 KB ) - added by Christian Boos 18 years ago.
For the record, the latest version of the div & span macro (for source:trunk@2500)
div_span_macros.diff (7.8 KB ) - added by Christian Boos 17 years ago.
Add builtin div and span wiki processors - suggested fix for 0.11
ticket2048-patches.diff (11.8 KB ) - added by Christian Boos 16 years ago.
Updated patch - on top of source:/sandbox/context-refactoring@6135

Download all attachments as: .zip

Change History (39)

by Christian Boos, 19 years ago

Attachment: 2048.patch added

patch against 0.9b1 (or close) for the proposed feature

comment:1 by Christopher Lenz, 19 years ago

I think this kind of stuff should be provided as a generic wiki macro, for example:

[[Block(warning)]]
==== Attention ====

Make sure you have PySQLite >= 1.1 installed to use SQLite 3.x.
[[Block]]

and (possibly):

[[Inline(todo)]]FIXME: better explanation[[Inline]]

These would get rendered as opening <div> or <span> tags, with the argument as value of the class attribute. When the macros are used without argument, a closing tag is rendered. Alternatively, we could provide four macros named [[BeginBlock]], [[EndBlock]], [[BeginInline]] and [[EndInline]]. Not sure which is better here (verbosity vs clarity).

I don't think we should be adding any more specific syntax constructs for specialized kinds of blocks. Different folks have very different requirements here, so instead of adding bloat to the core syntax, I'd rather see us adopt a generic solution like the one proposed above.

comment:2 by Christian Boos, 19 years ago

For the block syntax, I think I have a good idea: as the macro syntax already accept mimeview processors (e.g. [[html(...)]]), why not make it symmetrical, and allow blocks to call macros:

 {{{
 #!Block(warning)
 ==== Attention ====

 Make sure you have PySQLite >= 1.1 installed to use SQLite 3.x.
 }}} 

As for the notation proposed in this ticket, I think it's really a matter of verbosity vs. usability. Having to specify a todo style for a content saying also TODO would be a bit too verbose for most users. I'd prefer to have something shorter to type (and as expressive):

  • [[Inline(todo)]]TODO[[Inline]] → bad, too verbose
  • [[TODO]] → would be <span class="todo">TODO</span>
  • [[WARNING: don't do that]] → would be <span class="warning">WARNING: don't do that</span>

That notation would feel very similar to the one used for macros.

comment:3 by Christopher Lenz, 19 years ago

Milestone: 0.9.1
Priority: normalhigh
Summary: Add 'notice' style for the Wiki formattingWiki macros for generating `<div>`s and `<span>`s with classes

comment:4 by Christian Boos, 19 years ago

Another proposal:

[[todo]]
That would create a div with class="todo"
And it could contain a nested 
[[urgent]]
div with class="urgent"
[[/urgent]]
[[/todo]]

and:

[[todo]]That would create a span with class="todo" [[/todo]]

Using XML-like markup like <underline>...</underline> would be another option, but this would introduce backward incompatible changes.

comment:5 by Christian Boos, 19 years ago

Status: newassigned

Yet another proposal:

[[div(todo, background: #dfc, border: 2px dotted #0d0)]]

That would create a div with class="todo",
and it could contain a nested 

[[div(urgent, font-style: italic)]]
div with [[span(underline)]]class="urgent"[[/span]]
[[/div]]

[[/div]]

which would be rendered:

That would create a div with class="todo", and it could contain a nested

div with class="urgent"

Of course, we should provide a standard set of classes that could be of general use (like todo, warning, … we already have system-message). Additional classes should be added in customized templates, so generally there wouldn't be a need to specify manually the CSS.

And the macro itself:

class DivSpanMacro(Component):
    """
    Begin (`div` or `span`) or end (`/div` or `/span`) a division or a span,
    using the first argument as the class name.
    
    The remaining arguments are optional and allow configuring directly
    the style of the rendered element. Each argument is a `key:value` pair.
    """
    implements(IWikiMacroProvider)

    def get_macros(self):
        for name in ('div', '/div', 'span', '/span'):
            yield name

    def get_macro_description(self, name):
        return inspect.getdoc(DivMacro)

    def render_macro(self, req, name, content):
        # /div or /span: end the block
        if name[0] == '/':
            return '<%s>' % name
        args = content.split(',')
        # div or span: we expect the 1st argument to be a class name
        if len(args) == 0:
            raise Exception("Missing class name.")
        html_class = args[0]
        keyval_re = re.compile('^([-a-z0-9]+):(.*)')
        quoted_re = re.compile("^(?:\"|')(.*)(?:\"|')$")
        style = {}
        for arg in args[1:]:
            arg = arg.strip()
            match = keyval_re.search(arg)
            if match:
                key = match.group(1)
                val = match.group(2)
                m = quoted_re.search(val) # unquote &#34; character "
                if m:
                    val = m.group(1)
                style[key] = val
        styles = '; '.join(['%s:%s' % x for x in style.iteritems()])
        style_attr = styles and ' style="%s"' % styles or ''
        return '<%s class="%s"%s>' % (name, html_class, style_attr)

comment:6 by Christopher Lenz, 18 years ago

I don't agree about the builtin styles… if users need divs/spans with custom classes, they should be providing the CSS to do the layout. Also don't like allowing authors to specify inline styles, really.

Also, I still favor an explicit and somewhat more verbose syntax for blocks/divs:

[[BeginBlock(todo)]]
Bla bla bla bla
[[EndBlock]]

(I prefer the “block” to “div” as “block” is clearer about the intent IMHO.)

For spans, how about:

[[Inline(todo, I really need to do [ticket:123 this])]]

i.e. just include the text in the macro parameters.

We could provide [[BeginInline(todo)]] and [[EndInline]] for cases where spans need to be nested, which I think should be a really rare case.

Not stricly opposed to using “/” to end a block/span, need to think about that some more. :-P

comment:7 by Christian Boos, 18 years ago

If you want to do:

[[Inline(todo, I really need to do [ticket:123 this])]]

then you'd need a recursive step of parsing, on the arguments. We do that elsewhere too (titles for example) but that's not optimal (also, I wonder if there wouldn't be an alternative solution for parsing titles without recursion).

Not being verbose was precisely what motivated me to fill this ER, because one can already do that being verbose:

[[html(<div class="todo">)]]
Bla bla bla bla
[[html(</div>)]]

So, not sure what do here… looks like a draw :)

by Christian Boos, 18 years ago

Attachment: div-span-macro.patch added

For the record, the latest version of the div & span macro (for source:trunk@2500)

comment:8 by anonymous, 18 years ago

Keywords: tools added

comment:9 by anonymous, 18 years ago

Keywords: fun added

comment:10 by Matthew Good, 18 years ago

Keywords: tools fun removed

I don't think that those keywords are relevant. Please do not make edits to the tickets here for testing purposes. There is a demo site for that.

comment:11 by Christopher Lenz, 18 years ago

Milestone: 0.9.10.9.2

comment:12 by Pedro Algarvio <ufs@…>, 18 years ago

Have any of you seen WikiTemplates Plugin? I does what you want. Yeah, syntax aint that simple but it has much more potentiality.

comment:13 by Christopher Lenz, 18 years ago

Milestone: 0.9.31.0

comment:14 by Christopher Lenz, 18 years ago

Milestone: 1.00.10

comment:15 by Chris Ryland <cpr@…>, 18 years ago

I'd vote for something drop-dead simple, such as

[[[ Normal Wiki text block, but formatted in a colored box like but in a different color, perhaps. ]]]

This could serve as pretty much anything: note, warning, todo, etc. Perhaps one could provide a small set of "icons" as called out at the start, e.g.,

[[[ #Note This is important. ]]]

That seems like the least syntax, and is easily remembered as parallel to .

comment:16 by Chris Ryland <cpr@…>, 18 years ago

(Whoops, there are some missing triple-curly braces in that previous post.)

I'd vote for something drop-dead simple, such as

[ Normal Wiki text block, but formatted in a colored box like pre-formattet text but in a different color, perhaps. ]

This could serve as pretty much anything: note, warning, todo, etc. Perhaps one could provide a small set of "icons" as called out at the start, e.g.,

[ #Note This is important. ]

That seems like the least syntax, and is easily remembered as parallel to pre-formatted text.

comment:17 by Christian Boos, 18 years ago

Milestone: 0.10
Priority: highlow

I think I'll move the original request over to my TracHack:WikiGoodiesPlugin …
(i.e. having * TODO * render as TODO)

As for the more general macro, well, I don't know, maybe I'll get a better idea later.

comment:18 by Christian Boos, 17 years ago

Resolution: wontfix
Status: assignedclosed

See above, moved to TracHacks:WikiGoodiesPlugin.

comment:19 by Christopher Lenz, 17 years ago

Milestone: 0.11
Priority: lownormal
Resolution: wontfix
Severity: minornormal
Status: closedreopened

I do not agree with closing this. Being able to generate custom <div> and <span> elements in wiki text should be a core feature, especially now that HTML processor blocks no longer support leaving elements open!

comment:20 by Christian Boos, 17 years ago

Well, I was referring to my original request.

Maybe should start a fresh ticket, don't you think?

comment:21 by Christopher Lenz, 17 years ago

Seeing how all the relevant comments are in this ticket, and the summary has been adjusted, I don't think opening a new ticket would do any good.

comment:22 by Christian Boos, 17 years ago

Description: modified (diff)
Keywords: macro wikiprocessor added

Well, OK, so I'll also adapt the description, to make this clear.

Any new idea on the topic, by the way?

comment:23 by Christian Boos, 17 years ago

Status: reopenednew

Some new ideas: the syntax for generating <span> could be similar to the one of the macro call, but "opened":

 Do the checkout... [[small[[ (See screenshots below 
                               for help when using TortoiseSvn)
                    ]]small]]

(written on multiple lines on purpose, to show it's not a online [[<macro>[[...]]<macro>]] construct, but it doesn't need to be, of course).

That way, spans could be easily nested.

For <div>, one could do something similar using a special div WikiProcessor:

{{{
#!div(note)

'''Warning:''' This is important ...
}}}

Here again, this would easily allow for nesting, and is pretty close to the current way to do it using the html WikiProcessor.

Of course, this needs the ability to add arguments to WikiProcessors, something that was on my TODO list for some time now (e.g. would also give the ability to specify the annotations to be used for renderers).

comment:24 by Matthew Good, 17 years ago

The argument passing for WikiProcessors is a good idea, but I think I'd still prefer using a standard macro instead of adding a new syntax for [[class[[. Spans are used to do inline formatting, so requiring splitting the delimiters across lines seems counter-intuitive. It also doesn't seem to offer much benefit over [[span(small)]]some text[[/span]].

For <div>s I think we could use macros [[div]] and [[block]]. I like [[block]] myself, but I wouldn't mind providing both. For <span>s [[span]] and either [[inline]] or possibly [[style]]. I'd be +1 for adding macros div, block, and span and we can discuss an appropriate alias for span.

Passing arguments to WikiProcessors can be opened as a separate ticket since it applies beyond just this request, and we can extend these macros to support it once it's been implemented.

in reply to:  24 comment:25 by Christian Boos, 17 years ago

Replying to mgood:

Good points. Thanks for the feedback.

in reply to:  19 comment:26 by Christian Boos, 17 years ago

Replying to cmlenz:

I do not agree with closing this. Being able to generate custom <div> and <span> elements in wiki text should be a core feature, especially now that HTML processor blocks no longer support leaving elements open!

And as such, this solves the problem raised in #2428. But see the discussion there which would apply to the macros we're planning to implement here.

comment:27 by dkg-debian.org@…, 17 years ago

Cc: dkg-debian.org@… added

comment:28 by zimbatm@…, 17 years ago

Hello,

most proposed solutions are about using macros. Why not add a class-definition syntax to the parser ? Macros seems a bit too verbose and you need to apply the closing macro correctly. I propose the ".class-name" syntax which mimics the css definition pretty well and which would be applied to the current scope. It could be used in conjunction with other styles. Some examples :

'''Do that !'''.urgent
=> <b class="urgent">Do that !</b>

or

{{{

Alien code

\}}}.green-and-horrible
=> <pre class="green-and-horrible">

Alien code

</pre>
}}}

Also, I would note that allowing css attributes is not a good idea. Since the restrictions made on the HTML processor are here to avoid spam, allowing something like "{{{[[BeginHTML(display:none)]]<a href="some spam link">...}}}" defeats their purpose.

comment:29 by Christian Boos, 17 years ago

Priority: normalhigh

Nice proposal, I like it: it's clean, intuitive and easy to implement.

For blocks: (ignore the leading "|", it's just there in order to not mess up the formatting…)

|
| {{{
| ...
| }}}.urgent
|
| {{{
| #!sh
| echo note that this would work with WikiProcessors as well
| }}}.important
|

And for spans, I think we should allow adding .class on {{{...}}} spans only. This will be consistent with the block styling and won't be too troublesome to implement.

Example: {{{TODO}}}.important : TODO

We might even recurse within the {{{...}}} span, e.g. {{{TODO '''urgently'''}}}.important : TODO urgently

Also, with this syntax, it's quite easy to specify multiple classes for a block or a span, by simply chaining them: .class1.class2.

One thing left to do is to specify how the classes are added. Ok for not allowing arbitrary CSS attributes, but how are the CSS rules for those classes specified, and how will the Wiki editors know about the available classes?

For a start, we could define a few hardcoded classes and list them in WikiFormatting.

comment:30 by zimbatm@…, 17 years ago

Also, with this syntax, it's quite easy to specify multiple classes for a block or a span, by simply chaining them: .class1.class2.

Yes, I've alread tought of that. I'm not sure that class chaining is a good thing even if it's easily doable. The user has then to cope with CSS definition orders. Like .green.red is not the same as .red.green if both have a background-color attribute.

One thing left to do is to specify how the classes are added. Ok for not allowing arbitrary CSS attributes, but how are the CSS rules for those classes specified, and how will the Wiki editors know about the available classes?

Just edit the template's CSS and document them in the WikiFormatting page. Some default classes could be added or you could think of an admin panel to define those custom CSS but that can be done later.

Some interesting investigation could be done on the relation between the ticket attributes and CSS classes.. would it be useful to link severity or other attributes to CSS styles ?

Cheers,

zimbatm

comment:31 by Christian Boos, 17 years ago

Milestone: 0.11.10.11

comment:32 by ThurnerRupert, 17 years ago

Milestone: 0.110.11.1

nobody touched it for 3 months, its not a bug, so it seems to block 0.11 unecessarily …

comment:33 by Christopher Lenz, 17 years ago

Milestone: 0.11.10.11

This is not a bug per se, but it still needs to be addressed for 0.11, because we're taking away the ability to define "open" HTML blocks using the HTML processor.

by Christian Boos, 17 years ago

Attachment: div_span_macros.diff added

Add builtin div and span wiki processors - suggested fix for 0.11

by Christian Boos, 16 years ago

Attachment: ticket2048-patches.diff added

Updated patch - on top of source:/sandbox/context-refactoring@6135

comment:34 by Christian Boos, 16 years ago

Status: newassigned

comment:35 by Christian Boos, 16 years ago

Resolution: fixed
Severity: normalmajor
Status: assignedclosed

Update patch applied as a serie of changes in [6177:6182].

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Christian Boos.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Christian Boos to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.