When upgrading from Confluence 3.x to Confluence 4.x, the underlying storage format for your content will be migrated from a wiki markup-based format to a new XHTML-based format. This page describes the new storage format, and provides an opportunity for people to discuss the storage format and related ideas.

On this page:

Comments welcome

This page has attracted a lot of interest and a number of very valuable comments. Please have a read, to see the ideas that people have proposed.

Notes about the storage format

  • We refer to the Confluence storage format as 'XHTML-based'. To be correct, we should call it XML, because the Confluence storage format does not comply with the XHTML definition. In particular, Confluence includes custom elements for macros and more. We're using the term 'XHTML-based' to indicate that there is a large proportion of HTML in the storage format.

 

Under consideration

Provide an XSD - "an XSD could make on the fly validation for persons having an editor supporting it (e.g. Visual Studio), and since an XSD would be a way to validate your input. CONF-24884 - Getting issue details... STATUS

 

Another page available for further discussion

A new page is available as a place to continue discussions: Confluence 4 further discussion.

Please feel free to add your comments anywhere. We are not shutting down discussion on this page. We are supplying the new page to alleviate the problems caused by slow response on this page, due to the number of comments here.

  • No labels

187 Comments

  1. Please be sure to document the new syntax for all of your macros, namely:

    • The full content model for all your <ri:blah> and <ac:blah> elements: what sub-elements are required versus optional (if there are any sub-elements).
    • The full set of attributes for each of your <ri:blah> elements: what's required, what's optional, what the allowed values for each attribute are, and most importantly, what exactly each attribute value will do.

    Honestly, I'm not sure a simple table format like you're starting with here will accomplish this, at least not for your macros. Rember, the people who will need to edit the storage format directly will need to understand all of it. We're talking a full schema/DTD description in plain language.

    Perhaps one option is to document the high-level stuff in the table but for each element provide a link to a page (or subsection of a large page) that lists the full element declaration from your schema/DTD (personally I think DTD-style element declarations are more human-readable), along with the details? That way at least, people who are familiar with how to read SGML/XML schemas/DTDs can figure out what they can and cannot do.

  2. And to help you walk the line between expressing content models in an XSD manner or a DTD manner, here's the approach the OASIS technical committee that created the DITA specification used to specify content models in a neutral manner that enables people who prefer XSD declarations versus people who prefer DTD declarations to get the basic information they need:

    DITA language reference example for the FIGGROUP element

    Anecdotally, I was on the OASIS technical committee that produced the DITA 1.1 specification, and I've done a fair bit of DITA specialization work in the past. All the IBM luminaries who developed DITA and trained others taught by using DTDs and DTD declarations, and when I worked on DITA implementations we all worked with DTDs instead of schema to produce our specializations. The reason is simple; DTD-style element declarations are much easier for humans to read and parse. So if you're thinking of taking a shortcut and just pasting in your XSD declarations to explain the content models for your more complex macros, I'd recommend against that. If you guys prefer working with XSD internally, that's great, but either translate those to DTD models for posting in your language reference here, or create a neutral language reference as demonstrated in the provided link.

  3. It can be helpful even for your elements based on XHTML to clearly spell out any restrictions about which Confluence-unique elements can be placed inside them (or not). This is what I mean by specifying the full content model for every element in your XML schema. For example, can I put literally any of your <ac:blah> elements inside of an <li>? How about inside of a <tr>? Believe me, people will have these questions.

  4. Please publish (make available for download) a schema (XSD).

    Annotate the schema with human-readable documentation (in xs:documentation elements).

    Use an XSLT stylesheet to transform the schema into XHTML-source reference documentation.

    Publish the resulting reference documentation on the web.

    1. Perfect. Yes, please. (smile)

    2. Hi Graham, thanks for the feedback. How do you plan to make use of all the things you've requested?

      1. Hi Bill,

        How do you plan to make use of all the things you've requested?

        Immediate plans? None whatsoever. My company is still using Confluence 3.x in production. We have 4.x in a "sandbox" test environment.

        Another reason to not even consider my request: I work at a very small company (30+ employees).

        In case you're still reading...

        I plan to use the schema outside of Confluence, to create and edit Confluence XML source with my choice of validating XML editor, prior to importing/inserting into Confluence. (Or, similarly, to validate Confluence XML source with a command-line validating XML parser, such as xmllint from the libxml2 library.) This would enable me to create and edit Confluence source XML "offline" (away from a Confluence installation, or otherwise outside of the Confluence editor).

        XML validating editors such as Altova XMLSpy often use documentation annotations embedded in a schema to provide context-sensitive help. However, I find that dedicated XHTML-format (hyperlinked) schema documentation (created from annotated XML schemas), such as the examples at http://www.schemacentral.com/, offer a quicker and better way to explore and understand an XML vocabulary than context-sensitive help in an editor.

        By "create and edit [...] source", I do not necessarily mean manual data entry (creating content via keyboard input) using an editor. For example, I recently wrote a script that extracted information from a combination of software product source files (in different programming and markup languages; a mix of comments and programmatically significant parameter values), and then formatted it using wiki markup. I then pasted the wiki markup into a new Confluence page. The idea was to present to a lead (time-poor) software designer, in as concise a way as possible, some information from the product source (spread across hundreds of source files) that needed their review. They could quickly review and update the information in Confluence, leaving someone else (probably me!) to apply those changes to the many original version-controlled product source files. This is just one example of creating content for Confluence outside of Confluence. Yes, I did try pasting the wiki markup into the Confluence 4.x editor and, to your credit, it worked a treat: the editor translated the 4000+ lines of wiki markup (yes, perhaps it should have been more than one page!) into "rich text". (This is a one-way conversion only, though, right?)

        In the future, under Confluence 4.x, I can foresee that, rather than generating content for input to Confluence that is formatted using wiki markup, I might want to generate content that is formatted using the Confluence 4.x XML markup. Especially if the original content (outside of Confluence) is itself in XML. (To do that properly - to ensure I am generating content that is valid - I need a schema. I would prefer not to have to wait until I import/paste content into Confluence, and then have Confluence tell me it's invalid.)

        Which takes me back the past...

        As recently as the late 80s, parts of IBM were using a proprietary generalized markup language (GML), IBM BookMaster, as the common source format for internal software design documentation and external customer user documentation. The editing and formatting environment was also common: IBM's mainframe-based VM operating system, accessible to everyone in the organization via a terminal (or, more likely, even back then, a terminal emulator running on a PC). Technical writers (like me) could often copy design documentation (such as reference tables, or programming command reference information) directly to the user documentation (especially when we helped to prepare the design documentation!). Then, IBM started pulling the plug on VM: it migrated user documentation source to a proprietary SGML format, IBMIDDoc, involving a specialized set of third-party (for-money), mostly PC-based tools available only to technical writers, and it migrated design documentation source to PC-based word processing applications, such as Lotus Word Pro. Thus, the easy transition between design documentation and user documentation was lost; a situation that continues to this today, although the "strategic" source format for user documentation has since moved on to DITA (XML).

        I would like to return to a time when it was relatively easy to migrate portions of design documentation to user documentation without significant source-format conversion. A more ambitious dream is to have portions of design documentation actually be the user documentation. However, one current hindrance for me is that, due to various technical requirements and contractual obligations, my user documentation source must be in DITA. Moving the source format of Confluence from wiki markup to a semantic XML vocabulary such as XHTML offers the potential to make it easier to "round-trip" between an editing environment (and corresponding source format) available to everyone - Confluence! - and other semantic XML vocabularies such as DITA. I understand that other organizations might already be doing such round-tripping in Confluence 3.x, but the ability to use XSLT to translate between semantic XML vocabularies would make this task much easier.

        I note your use of the word "all" in "all the things you've requested", and it troubles me. It makes me think that you think I'm asking for a lot.

        Essentially, I'm requesting just one thing: an annotated schema.

        To me, this request is verging on stating the bleeding obvious; common courtesy; a given. If you create an XML vocabulary that you expect other people to use, then you provide a schema. Developing a schema without annotations is similar to developing program code without comments. I'm curious: specifically which aspect of my request tipped you into writing "all"?

        My personal preference is XSD, although I acknowledge the shortcomings of the W3C XML Schema 1.0 language mentioned by others. A nice-to-have would be XHTML-source documentation, published on the web, generated from that schema (XSD-to-XHTML via XSLT), but if you don't publish that, then I'll bet someone else will.

        I do think it strange that you haven't already said "here is the schema" (a .zip downloadable from your website). Don't you already have a schema? Otherwise, (how) are you validating your own XML source format? (Er, using your own bespoke code, that doesn't use a schema?)

        If you do not already have a schema, then take the XHTML schema (1.0 Strict? Whatever version you are using as the basis for your XML source format), and extend that to include your proprietary markup. I routinely directly edit XSDs (that is, as XML source; not just as presented by some GUI schema design application). If I can do it, it's not that hard! Just how many proprietary elements/attributes have you defined?

        I've read the W3C software notice and license, and there doesn't appear to be anything in there that would legally prevent you from doing this, as long as you meet their brief list of requirements ("Permission to use, copy, modify ... provided that you ...").

        1. Essentially, I'm requesting just one thing: an annotated schema.

          To me, this request is verging on stating the bleeding obvious; common courtesy; a given. If you create an XML vocabulary that you expect other people to use, then you provide a schema. Developing a schema without annotations is similar to developing program code without comments. I'm curious: specifically which aspect of my request tipped you into writing "all"?

          This. Exactly. It should be a no-brainer requirement that if your Confluence users (some of them at least) must work with your proprietary XML schema (please stop calling it "XHTML with some additions", because that most decidedly makes it not XHTML) to achieve some common use cases, then you simply must document a language reference for them. Not a half-ass table that tells part of the story, but a complete language reference that tells all of the story.

          Again, I ask: "exactly which Confluence "macro" elements can I place inside of your schema's <td> element? How about which macro elements can I place inside of your schema's element that equates to the old {info} macro? What are the nesting rules? What are the ordering rules? What is the exact content model for every single element in your schema?

          Graham's suggested approach is the simplest way to build this type of needed language reference. His approach also makes it possible to use external validating XML editors and CLI parsers, because you're providing the XSD itself for use in such third-party tools.

          And again, please stop saying your schema "should be familiar to everyone because it's just XHTML with some additions". Will a validating editor that knows how to parse an XHTML document know what to do with one of your source pages? No. Because your schema includes a bunch of other element declarations and content models that are not part of the XHTML schema. And because even the elements that you borrowed/adapted from XHTML must have element declarations specific to your schema that enable you to place your various <ri:blah> and <ac:blah> macro elements inside of them. For example, to put an <ac:emoticon> element inside of a <p> element in your schema requires an element declaration for <p> that expressly allows the <ac:emoticon> element in the content model for <p>. Your <p> element is therefore no longer the same thing as the <p> element from the XHTML schema, and attempting to parse a storage format page from Confluence in some 3rd party editor that knows how to validate XHTML will just barf on your storage format.

        2. Anonymous

          Hello everybody,

          I just came across this page while searching for exactly what Graham is requesting. Until now I was sure such a shema must be available somewehre...

          I'm aware of the hassel this may produce when adding third party macros, but I would appreciate an XML-Schema-Definition with all the "out-of-the-box" features very much.

          thanks a lot in advance
          Andreas Schauerte

          1. Developing a schema without annotations is similar to developing program code without comments.

            What a bad comparison by today's standard, code that requires comments is by definitions often "bad code" because we strife to make code self-explanatory. Anyways that was not my point to make here.

            I'm aware of the hassel this may produce when adding third party macros

            This is exactly why I don't expect macro's to be documented further than to the "general structure", keep in mind that 2 different versions of the same macro may even result in different parameters, valid values, optional parameters and so on.

            I have worked with plugin architectures the past 4 years now and there is many implications to this. One must keep in mind that the interface your plugin developers must conform to is also an interface that should be as simple, intuitive and lean as possible, forcing to many things on those developers means less development and that would be a huge setback to Confluence, one of the strong suits is the many plugins that exist.

            This kind of documentation should instead be accompanied by the plugin it self. Not on a general page as this.

            I have yet to test the new Advanced Editor, that will most likely not happen until it is out of beta, however the best Atlassian can do is provide the means for the Plugin developers, AT FREE WILL (important) to provide documentation, and so on on their plugin, requiring it will be damaging. You could properly even allow the developer to attach a partial XSD for validating his/hers specific macro, but again, requiring such thing is a bit much to ask.

            Developers is just another set of users and those require as much consideration as anyone else.

            Now I have NO idea on how plugins for Confluence is structure as I am not a developer on that front, but Atlassian provided the means to document examples and use of deployed plugins prior to 4.0 through a Help menu of some sort, ofc. this won't satisfy the need for "offline editing", but there is only so much that is actually possible without causing pain else where.

            So I would be perfectly satisfied if the macro part of the XSD ONLY required:

             

            //Outer structure: name required but it does not have to exist to mitigate migration of confluence content from one instance to another where the same plugins are not yet installed.
            <ac:macro ac:name="code"> 
                //Inner structure: 0..N Parameters, name required, no validation against if the macro accepts this or not to mitigate changes between plugin versions as well as data migration as above.
                <ac:parameter ac:name="title">This is my title</ac:parameter>
                <ac:parameter ac:name="linenumbers">true</ac:parameter>
                <ac:parameter ac:name="language">html/xml</ac:parameter>
                //Inner structure: Plan-text-body, required or not???... I suppose not all macros would need one. But I would guess that the <ac:macro> tag would only allow for 1, so it is either A 0..1 or 1..1.
                <ac:plain-text-body><![CDATA[this is my code]]></ac:plain-text-body>
            </ac:macro>

             

            I Hope you understand the annotations above.

      2. Hi Bill,

        I answered your question a while ago:

        How do you plan to make use of all the things you've requested?

        but I've continued thinking about how I could help you with "all the things".

        Regarding the following two things:

        Use an XSLT stylesheet to transform the schema into XHTML-source reference documentation.

        Publish the resulting reference documentation on the web.

        I have contacted the developer of www.schemacentral.com.

        From my correspondence to the developer:

        I am a user of a commercial wiki product called Atlassian Confluence. Atlassian has recently changed their content source format from wiki markup to their own proprietary XML vocabulary based on XHTML ... with their own ac:-namespace prefix elements.

        ...

        How do you generate the XHTML documentation presented on the Schema Central website? I imagine that at least part of the answer is "we use an XSLT stylesheet to transform XSD file(s) into XHTML"

        ...

        If Atlassian publish a schema, would you consider generating and publishing the schema documentation on Schema Central?

        My aim is to make it easy for Atlassian to provide comprehensive human-readable documentation for their new Confluence XML source format. Schema Central is the best solution I've seen.

        From the developer's generous reply (which the developer has given me permission to quote here):

        I do use XSLT

        ...

        I would be happy to add the Confluence schema to Schema Central, provided that they don’t put some kind of restrictive copyright statement on their schema.  But even if they did, I’d be happy to generate the HTML and send it to you.

        1. Thanks for your responses, Graham. The schema is something we want to look into generating at some point - right now we're working on the "edit source" plugin and continually improving reliability of the editor.

          1. Thanks for the reply, Bill.

            From your reply:

            The schema is something we want to look into generating at some point - right now we're working on the "edit source" plugin ...

            I infer from this statement that you do not see a schema as being intrinsic to the development of the "edit source" plugin.

            This, together with your continued silence to the repeated question "how are you currently validating your XML source format?" (I note that others have asked similar questions in comments on other pages), leads me to the conclusion that you are not currently validating your XML source, and that you have no immediate plan to have the "edit source" plugin perform validation, either.

            I hope that I am wrong on both counts.

            1. I'm with Graham on this. How on earth did you get this far with your storage format and your new RTE without actually having an XSD or DTD already in place? How are you validating what's in the RTE before saving it to storage format?

              Even if creating an XSD-based language reference doc is not on your radar right now, can you at least publish the XSD so that it can be examined and used in third party XML-aware editors if necessary?

            2. This, together with your continued silence to the repeated question "how are you currently validating your XML source format?" (I note that others have asked similar questions in comments on other pages), leads me to the conclusion that you are not currently validating your XML source, and that you have no immediate plan to have the "edit source" plugin perform validation, either.

              Hi Graham, the source is validated within various levels of server-side and client-side code, both for validating the content syntax and for preventing the posting of malicious code. The edit source plugin will use same the validation mechanisms. So yes, we do most certainly do validation but it's not using an XSD.

              1. So yes, we do most certainly do validation but it's not using an XSD

                Bill, I strongly recommend that you (and your architects?) look closely at sections 2.3 and 2.4 of the W3C XML Schema specification. Here's the lazy link: http://www.w3.org/TR/xmlschema-1/#concepts-schemaConstraints

                From your reply above, it seems that your validation is "minimally conforming". I humbly submit that this is not really good enough for primetime production use. Your validation should be "fully conforming". Not to beleaguer the point, but we didn't ask for Confluence to suddenly transform from a wiki syntax environment to a full blown XML environment. If you're going to force us to work with XML-based source, you should do it right; not halfway. There are valid business reasons for the things Graham and I have been asking for with regard to the XSD, the style of validation performed by your advanced editor, etc. I've been doing SGML/XML/DITA implementations on and off since 1993. I know the pain points, and it's clear that Graham does too. The question is whether you and your (other?) Confluence architects have enough experience with XML to know the pain points and value the strong suggestions by experienced SGML/XML wranglers in your user community.

                Again with specific regard to your V1 release of the advanced editor, the showstopper problem with your implementation is that your binary-based minimal validation is unilaterally deleting markup that it considers invalid upon save. This is a huge problem. Huge. To me, it demonstrates that you guys don't have enough hands-on with big XML doc implementations. There are shortcuts, there are "early look" releases, and there are "this should never have been released even in beta form" issues like I feel your V1 will be.  Again, I point to Arsenale's Invisible Ink plug-in. They "get it". They understand how XML works in a real production sense. Their plug in does what appears to be fully conforming validation and it does not delete markup it considers invalid. Instead, it reports what it thinks is invalid and refuses to save the document.

                That is exactly what your advanced editor should do too, and IMO you're crazy to roll out even a "beta" V1 that will unilaterally delete markup it considers invalid.

                And lest you be tempted to think "what's the big deal? You can always revert to the previous version of the page if something gets deleted by the advanced editor, right?" No. Wrong. The problem is that you might edit the page in the advanced editor  to fix a problem with a table cell that got accidentally deleted. Meanwhile, unknownst to you, you accidentally add an extra character to some tag that delimits an important "warning" special notice elsewhere on the page. So your validation code says "hmm this element is invalid, i'll save the page but strip this out."

                Net result? An author might not even be aware that your editor deleted potentially important content, because it had nothing to do with the thing the author went into the advanced editor to fix. What if that "warning" special notice was about a physically dangerous act that could result in injury or death? You really want that on your conscience? Does your legal department want to wrangle with a wrongful death suit because it can be proven that your editor stripped out the warning without telling the author? Think about it!

  5. For examples of human-readable schema documentation, see:

    http://www.schemacentral.com/

    1. I'd been looking for something like this. It has some of the schemas I've been trying to wrap my head around (Dublin Core) but not others (RDF). It looks like a good resource. 

      1. You've probably already found this link by now, but just in case:

        Confluence resources (including schema and schema documentation for the Confluence storage format)

        The schema documentation for the Confluence storage format was generated by the (very kind) owner of Schema Central.

  6. I thought I'd revisit this page to see if you had removed "(Still considering)" from the "Provide an XSD" to-do item. Nope. It's still there.

    Some further thoughts, while I'm here...

    Academic discussion: XHTML as your XML source format

    There are strong arguments (that I might make myself) against creating XHTML that is valid but subverts the semantics of XHTML, and what I'm about to discuss (I'm deliberately not using the word "suggest") might come close to, or perhaps cross, that line, but I can't help noticing: I've yet to see any Confluence 4.x source documented in the body of this page that I think could not have been coded in XHTML 1.0 Strict (I'm deliberately not referring to (X)HTML5... yet).

    For example, instead of coining the ac:macro (and ac:link) and ac:parameter elements, you might have used the XHTML elements object and param.

    I realize that this discussion is academic. This - using XHTML as-is, or coining your own XML vocabulary - would have been the kind of early design decision that you made after careful deliberation. And I am not saying that you made the wrong decision. Neither am I saying that this XHTML - with, for example, XHTML object elements in place of ac:macro - would have been what you actually presented in browsers. No, this XHTML would have been your XML storage format. To produce "presentation-level" XHTML, you'd convert those object elements into (probably) object-element-free XHTML.

    So why even discuss it? You'd have saved yourself the trouble of having to customize the XHTML schema, because your XML storage format would have been valid XHTML, and I/you/we would have been able to use validating XML editors with the (unchanged) XHTML schema.

    I understand that coining your own Confluence-specific XML vocabulary frees you from the constraints of the XHTML vocabulary and any taint of subverting the XHTML semantics to your own proprietary ends. Coining your own vocabulary also offers the potential for tighter validation: you can require certain Confluence-specific markup, rather than expecting, but not being able to use the xHTML schema to validate, certain combinations of XHTML elements (expected by macros.) Having said that (as has been pointed out by Shannon), the W3C XML Schema 1.0 language ("XSD") has some limitations here (DTDs have limitations, too: http://www.w3.org/TR/xhtml1-schema/#why).

    Style attributes, but not class attributes?

    I note that, in the "XHTML portions" of your source format, you've (so far) avoided any use of class attributes: you've opted for style attributes instead. I'm a little curious about that.

    I also wonder why you've wrapped your "square bullet" lists in a <div> (but perhaps that's a typo).

    (And I wish that you'd used the default - as in, default CSS implemented by most browsers - vertical spacing for ordered and unordered lists, rather than bringing forward the Confluence 3.x "compact" style, but that's getting off-topic.)

    How are you validating your XML source format?

    I've asked this question in previous comments, so far, without a response: how are you currently validating your XML source format?

  7. So: you've released the "beta" V1 advanced editor now. Do you realize that you have NOT given us enough information above to support use of this editor? Where are the content models? The specific content models for every possible element.

    C'mon Atlassian, this is XML 101 and you are FAILING. Yes, I'm pissed. Just document the XSD or DTD already, in a standard XML language reference spec format. Sheesh, I could have done this in my sleep in 20 person hours or less if you would just show me the DTD/XSD.

    BTW, Graham has already given you the keys to the kingdom above. You don't even have to commit your own tech writing resources to the effort. Some other third party volunteered to do a proper language reference for you.

    1. Hi Shannon, we understand this is an important to you and Graham and appreciate your comments thus far. This page is intended to give a developer or and advanced user of the source editor an idea of how the storage format works for core elements... not to be a comprehensive guide for the syntax for every single macro you might have in your system. To understand the content model for a specific element, you'll want to insert it via the WYSIWYG editor and then view the storage format. We're currently gauging the demand for an XSD / DTD (please vote at CONF-24884 - Getting issue details... STATUS ) but, as stated in comments above, it would require development work and detract from other highly demanded fixes and features.

      1. Do your devs think they could code your web interface without an (X)HTML language reference? Without a CSS reference? How about the move to HTML 5? Think they could have done any of your HTML 5-based features without an HTML 5 language reference?

        It is mind-boggling that Atlassian is even considering not providing a language reference for your XML storage format. You guys had won me back for a while, but now you have seriously, and I mean seriously lost me again.  Your current v1 advanced editor is truly worthless without a bona fide language reference. I cannot be any more emphatic on this point.

        1. For any other interested parties, I'll post another link to "vote" at:

          Message the CEOs

      2. Bill, it's not just Shannon and Graham that this is important too, it's elementary stuff and causing pain for others too. Shannon and Graham are doing a good job of raising the core issues; up until now I've been content to let them speak for me too, but your comment seems to suggest you think it's only them who are having issues.

        1. Thanks for lending your voice, Niall. I'd also like to remind the Confluence PMs and Architects that the people who post here each represent many other users at their organizations. Not every Confluence user  will be aware enough and engaged enough to come here directly. Instead, they will complain to their enterprise's "Confluence person", and only that person is likely at all to come here and post.

          Speaking for myself, I represent a 500-user license for both Confluence and JIRA. I am "the Confluence guy" for my enterprise. I have nearly 100 active contributors in my Confluence environment, comprising Engineering devs, tech writers, and QAs; data scientists; solutions engineers; engagement managers; customer success managers; and operations staff for our cloud server environments.

          Believe me, I speak for ALL of them when I say that they will routinely need to be able to fix bugs caused by the RTE, and that most of them will not have the deep understanding of XML syntax nor the patience to thrash around and reverse engineer what the syntax for any given element should be. They will all, to a person, require a language reference for the syntax of the storage format to get their jobs done. If they don't have a real and complete language reference, they will be bugging me constantly, and they will be complaining to me constantly.

  8. I feel that I am one of several users who have tried but so far failed to encourage you (Atlassian) to publish a schema for your XML storage format.

    In your own words, a schema (or DTD) is something that you're "still considering"; at best, most recently, following (but I realize not necessarily prompted by) encouragement from myself and others, "something we want to look into generating at some point". (How's that for a definite commitment? "want to... look into... at some point"!) Not a requirement; not a "given".

    I have voted for CONF-24884 - Getting issue details... STATUS but frankly, I'm tired of trying to convince you.

    1. Squeaky wheels and all that. Graham, before you give up entirely, I encourage you to escalate directly to the CEOs. Link above.

  9. One more attempt to talk sense into the Atlassian PMs and architects regarding your perception that a fully documented language reference for your XML schema isn't desired by enough customers to be worth the development effort.

    Premise A: Not many of your existing wiki users have experience with XML-based documentation authoring environments. XML is still a 'big player' or 'bleeding edge' technology in the general world of tech writing and documentation. Because not many of your existing wiki users have experience, they are not familiar with the pain points of working in XML syntax.

    Premise B: The four people in this conversation thread (and related CONF-24884) who obviously have significant XML-based authoring experience are all telling you the same exact thing: you must provide a proper language reference and you must provide an XSD/DTD. That's me, Graham, Andreas, and Kathleen.

    So: everyone who knows the pain points is telling you that this is mandatory to provide. Everyone else that you are expecting to convince you of the need via "voting" are (no insult intended) ignorant of the pain points and therefore won't be motivated to vote.

    In short, you are going about this entirely the wrong way.

  10. I was reluctant to publish the details of the storage format at all. Publishing something makes it part of the API, and as has been exhaustively detailed here, the format is not yet "API-worthy". We wavered for some time between publishing, or keeping it internal until it was "ready", and ultimately decided based on a deluge of feedback that a flawed, ad-hoc documented format beats an unpublished format that might become pure enough to publish in the future.

    Software development is a trade-off between competing priorities. The priority for Confluence 4.0 was concentrating on the editor itself and treating the storage format as an implementation detail. Would it have been nice to clean up the flagrant abuse of style attributes before release? Absolutely. Would we have liked to have a published schema on day zero? Absolutely. Would it have been worth the dozen or so major editor bugs that wouldn't have been fixed in order to get that done? Probably not.

    Wiki markup, Confluence previous storage format, was proprietary, barely documented, inconsistent, ludicrously broken (c.f. escaping, nested elements, whitespace, macro syntax, block vs inline markup, the interaction of tables and lists etc. etc.), only parseable through a mess of ad hoc Java code and regular expressions held deep in the Confluence codebase, and completely un-amenable to deterministic round-tripping to other formats.

    (I'm always amazed, considering the amount of developer time we had to pour into the The Universal Wiki Converter, how wiki markup somehow gets a free pass in the "impenetrable proprietary format" stakes.)

    The new format, while not a good XML citizen by any stretch of the imagination, is still orders of magnitude easier for third parties to parse and transform than the previous one. Converting the storage format into a good XML citizen (or creating a public-facing API that is a good XML citizen) is a goal we've had since the beginning, but not one we were able to deliver on in the 1.0 release.

    1. The problem is that the partial "doc" you have given us above is inadequate to understand what the basic structure (more properly known as the content model) of your XML syntax is. It's been pretty obvious for a while now that you guys aren't working internally from either a DTD or XSD: you've been very evasive or silent when asked directly "how are you validating your storage format against your own schema?" Bill also finally let slip either above or in a related thread for the advanced editor that that your validation code is not done with a standard XML parser library, but is instead hand-rolled validation at various levels.

      But let's leave the question of an XSD or DTD aside for the moment, shall we? Or as you put it "what would be needed to make your storage format a 'good XML citizen'".

      Regardless of whether or not we can have an XSD/DTD today, which would enable a number of use cases that are currently impossible, the primary use case that caused you to change your course a couple months ago and develop your advanced editor and this current half-finished doc for the storage format is a very very VERY simple and pervasive use case:

      Your RTE is broken and full of bugs. It is far from perfect. It will NEVER BE perfect. No RTE has ever achieved perfection before (especially browser-based ones), so what makes you think you guys are going to be able to build the perfect mouse trap where everyone else has failed before? So: this means that your users will always need to contend with "bugs" and "broken" pages created by the faults of your RTE. Which means they need to go into the underlying storage format from which the final version of your pages are rendered, and they'll need to fix the problems with the storage format itself.

      So with that in mind as the primary use case you must solve ASAP to support the people who struggle with all the crazy, unintuitive ways your RTE currently breaks pages right and left, whether you can give us an XSD now or not, you must at least fully document your XML content models as they stand right now. I don't care if doing so exposes how "ugly" your XML implementation currently is. I care only that I can understand what elements I can put where. What attributes I can put where. What values I can put in those attributes.

      I'll ask several questions (some of which I've asked before), to demonstrate this point. You guys keep reiterating that your storage format schema is "essentially XHTML with some added elements for our macros". Oh really now? So if I look up an XHTML language reference I'll know what I can and can't do in your advanced editor? No, that's not true and we both know it. So then:

      • Gee, which version of XHTML are you based on and therefore support? 1.0 Strict? 1.0 Transitional? 1.0 Frameset? Basic 1.1 (with the ruby annotation elements and the removal of certain attributes from the 1.0 specs)? Which is it?
      • Exactly which Confluence macros can I place inside a TD element?
      • Does your table implementation support COLGROUP and COL elements? How about TFOOT or THEAD?
      • Exactly which macros can I place inside an LI element?
      • Does your storage format support OPTGROUP and OPTION elements? How about AREA elements?
      • Do you support DFN elements? What macros can I put inside a DFN element?
      • Are the content models for the elements you've borrowed from XHTML exactly the same as documented elsewhere in XHTML (or HTML 4.01) language references? Do you support exactly the same attributes? Or are there subtle differences, such as some attributes or interior nestings that you do not support in your schema?
      • What is the content model of your {BLAHBLAH} macro? What are the required versus optional attributes for it? What are the possible values for each attribute? Which are CDATA? Which are enumerated (and what are the allowed values in enumerated attributres)?

      I could go on and on and on with questions like these. These questions are what either a DTD or XSD could answer for someone who knows how to read and write such artifacts. But for most people who need information about your schema to support the primary use case I've outlined above, an XSD/DTD won't cut it because to them it would be so much gobbledygook. For most of your user base who will need to fix bugs caused by your RTE they will need a straightforward language reference that describes:

      1. Every element you support: both the ones based on XHTML and every one of your proprietary macro elements.
      2. For each such element you support, a description of the complete content modelfor that element:
        • Which other elements can be placed inside of it, and in which order? Which elements can it be placed inside of?
        • What attributes are required versus optional for the element?
        • What values are possible in each attribute?
      3. And most importantly, what is a "plain English" description of each element and attribute/value pair?
      Without this information, how can anyone know what to do in your advanced editor? You seriously expect us to thrash around and experiment to reverse-engineer for ourselves these details that you should be providing us?  This would be like if you'd originally released Confluence by saying "Hey! Here's a really great wiki engine! We have tons of cool macros! Have fun!" and then never documented your wiki syntax. This would be like the developers of any programming language (Java, Python, you name it) saying "Hey, here's this cool new programming language! It does really neat stuff!" And providing only a few syntax examples without actually documenting their complete language syntax.
      That's exactly what you have above, at this timestamp. A bunch of examples, but not a complete language syntax.

       

       

       

      1. And to be perfectly clear (and frank): your "documentation" for the storage format as it exists above at this timestamp is laughably and woefully inadequate. It's obvious whoever wrote it is shooting for a minimalist approach that "encourages exploration" from the intended audience.

        Well: I'm the intended audience. I'm even expert at XML, so my skillset extends far beyond the basic assumptions for the intended audience. I'm also well-versed in minimalist documentation principles. I'm also capable of a lot of exploration in this subject domain.

        But your "documentation" above is completely inadequate to support even me. It's certainly not going to support the typical user who needs to thrash around with the primary use case for your advanced editor.

    2. Personally I encourage the early release of this.

      Sure it is very limited what there is here, sure it is not really "API" ready yet, you make sure to say this at the top of the page, although it could have been done even more explicitly.

      But to me this allows for early feed back, and this means you will be able to adjust much faster rather than ending up with a complete 50 page reference for the confluence markup only to get users to say "We can't use this for anything".

      At the end of they day this is a "Take it or leave it". I mean if people does not think it is good enough yet, not ready to use, then don't use it. Any arguments about that this should have been there at the release of 4.0 is pointless at this point, it wasn't and we can't change that now, all we can do is to make of it what we can.

      I don't particularly like to defend you these days because I think to many heads at Atlassian are making to many communicative mistakes around the 4.0 instead of just looking at things for what they are and be honest, a trade-off was made, your not going to save customers by sugarcoating it.

      So (thumbs up) for that.

       

      As a side note...

      Wiki markup, Confluence previous storage format, was proprietary, barely documented, inconsistent, ludicrously broken (c.f. escaping, nested elements, whitespace, macro syntax, block vs inline markup, the interaction of tables and lists etc. etc.), only parseable through a mess of ad hoc Java code and regular expressions held deep in the Confluence codebase, and completely un-amenable to deterministic round-tripping to other formats.

      That is fundamentally wrong, we as programmers are just (still) incapable of replicating the process of us humans read, structures and parses things, so we fall back to well defined structured data. But that is a whole other subject of the computers understanding and the humans understanding, it is an extremely exiting subject however, short example to think about in this subject, take sorting the numbers 2,9,7,4,1,6,5,3,8... doing that in code is an extremely complex process, doing that using 9 blocks in front of you is the simplest thing ever...

      1. I don't particularly care if this is an early or beta release of the advanced editor and its supporting language reference. It's fine if this is an "early access" or "beta" or "first look" of the editor and its supporting doc. It's fine if the incomplete doc is currently incomplete, as long as Atlassian fully commits to actually completing the doc in the near future for the "real" release of the advanced editor. (I've stated previously that its in too rough and too early of a state for me to bother finding the bandwidth to even try it out, but that's just me and my work constraints. When you've got a real editor with real doc, I can proceed with the rest of my 3.5.x > 4.x migration test plan and hopefully green-light my enterprise for a 4.x migration.)

        What I do care about was Bill Arconati's very definitive statement just a few posts above that:

        This page is intended to give a developer or and advanced user of the source editor an idea of how the storage format works for core elements... not to be a comprehensive guide for the syntax for every single macro you might have in your system. To understand the content model for a specific element, you'll want to insert it via the WYSIWYG editor and then view the storage format.

        No. Just no. That clearly states an intent by Atlassian that this is all we'll ever get, documentation-wise. And that is a non-starter. That is not acceptable. That does not adequately support the primary use case for the Advanced Editor, let alone any other use cases.

        And to be clear: I'm not expecting Atlassian to document all the 3rd-party macros too. Of course not. Each third-party plugin will have to be evaluated on its own merits re their doc quality or lack thereof. But what I do expect is for Atlassian to document all of their own core macros. All of them. Not just a few "examples".

    3. Would we have liked to have a published schema on day zero? Absolutely. Would it have been worth the dozen or so major editor bugs that wouldn't have been fixed in order to get that done? Probably not.

      Charles, with respect (two thumbs up for your "Absolutely"), in my opinion, this is a weak argument based on poor design and development practice. You (Atlassian) had a starting point for your own schema the moment you decided to base your XML vocabulary on XHTML. Your schema should have been an artifact of the design and development of your XML source format. From the very start, you should have decided which, if any, XHTML structures you did not want to support, and updated your schema to match. Then, as you introduced new structures, you should have updated the schema to include those new structures. Not just as a nice-to-have for customers (as Bill wrote: "want to... look into... at some point"). But as the primary reference for the design, development, and testing of your source format. For example, used by your RTE developers (preferably, integrated into/referenced by the RTE code itself), and by your testers to ensure that the RTE produced only valid XML.

      Unfortunately, now, you have a growing base of Confluence 4 XML source that has not been validated to any schema. You might find that you've allowed (or the RTE has created) structures that you regret, and that you'd rather not encode as being valid in the schema. Oops. Setting aside your own proprietary elements - in which contexts they are allowed, and which proprietary and XHTML elements they allow as dependents - given that you've not been validating your source format against a schema, it's possible that even XHTML-only snippets in your source might not be valid XHTML.

  11. And this one is just for Bill Arconati, who said above:

    To understand the content model for a specific element, you'll want to insert it via the WYSIWYG editor and then view the storage format.

    Bill, your suggested process will most definitely, absolutely, not yield a "content model". It will instead yield only one possible instance of a content model, from which it will be impossible to extrapolate the actual content model. Do I really need to explain the difference here?

  12. And this one is for Charles Miller, who said above:

    Software development is a trade-off between competing priorities. The priority for Confluence 4.0 was concentrating on the editor itself and treating the storage format as an implementation detail. Would it have been nice to clean up the flagrant abuse of style attributes before release? Absolutely. Would we have liked to have a published schema on day zero? Absolutely. Would it have been worth the dozen or so major editor bugs that wouldn't have been fixed in order to get that done? Probably not.

    You still have myriad major editor bugs. Until you fix all major (and minor) bugs–an impossible task, btw–your users need a way to work around the bugs. Releasing the new RTE without a way to fix the editor's bugs in the underlying storage format was a huge tactical mistake, and you're still paying for it even now, nearly 6 months after your first release of the new RTE. Why do you suppose that nearly every comment on these various 4.0 Editor feedback pages is negative and scathing? Where are the ardent admirers who really appreciate your new editor and come here to defend the harsh criticisms and complaints that have been posted here for the past 6 months? The best your CEOs could come up with were a handful of cherrypicked tweets and an assertion that they'd received some nice emails from happy customers. As I said then: if this is true then like any product with a user community, there would be equal representation in your discussion forums by both the fanboys and the haters. Which is not the case.

    I understand competing priorities for software development; I've been in the field for 25 years. You picked the wrong priorities at first, and now you're doing damage control and triage. That's fine; we all make mistakes. Nobody expects Atlassian to be perfect. But we do expect you to be responsive when it turns out that your strategic and tactical decisions were obvious mistakes and your user community is telling you what they need to recover from those mistakes.

    What I'm concerned about here and now in this thread is the apparent risk that Atlassian is going to prolong a fundamental mistake here: which is not giving us the tools we need to work around the bugs with your new editor. It does not matter if your current XML implementation is ugly and malformed and full of hacks. What matters is telling us what your storage logic and rendering engine will accept as valid. If you don't tell us what the exact content models are, we cannot debug the storage format. It's really that simple. It does not matter whether it's ugly; just tell us what it is right now so we can recover the lost ability we've always had in 3.5.x and prior: the ability to work around bugs in your editors by just fixing the underlying storage format to do what we need it to.

    Wiki markup, Confluence previous storage format, was proprietary, barely documented, inconsistent, ludicrously broken (c.f. escaping, nested elements, whitespace, macro syntax, block vs inline markup, the interaction of tables and lists etc. etc.), only parseable through a mess of ad hoc Java code and regular expressions held deep in the Confluence codebase, and completely un-amenable to deterministic round-tripping to other formats.

    As Jens Melgaard points out very eloquently above, you're making a fundamental error of logic here. Wikis are primarily used by people, not by code. What's difficult for code can often be trivial for people. The main selling point of wiki syntax is in its simplicity and human-friendly nature. It is FAST to work with.  XML and all semantic markup is designed to be good for code at the expense of being good for people. Now, you've made your strategic decisions in this regard and I won't rehash the arguable wisdom of that strategic move. But right here, right now, you have to empower the people to work around the serious and numerous bugs and flaws with your code, which in this specific case means your current very unpolished RTE. And that empowerment takes the form of an advanced editor to directly manipulate the storage format as well as the full documentation for the storage format. Not a handful of examples and a misguided suggestion to just look at a specific instance of a macro if you want to learn its underlying content model (which is an impossible task in many/most cases).

     

  13. So you've "finalized" this storage format "documentation" as of today. I have many comments:

    • You guys really aren't done. <beatdeadhorse>This is unacceptable documentation for an XML language reference. It's a crime that you don't have an XSD or DTD, that you won't publish that XSD or DTD, and that your internal validation code is not validating against an XSD or DTD. You fail at XML 101. I'm frankly shocked that despite several people attempting to educate you guys over the past three months, you still don't "get it".</beatdeadhorse>
    • Regarding link bodies, why on earth do you bother with having both a PCDATA link body element and a CDATA link body element? That's just confusing. Why not stick with a single PCDATA body (<ac:link-body>)? Why does your RTE code create so many ugly, difficult to type and difficult to visually parse CDATA link bodies instead of just using <ac:link-body> with no markup inside the body? Seriously, what does the CDATA format for a link body buy you in terms of performance? How often do you ever see raw CDATA code like that in doc-oriented XML markup? I mean, really: you're forcing two different user patterns on your "advanced users" when clearly, one alone would suffice in all use cases (the PCDATA version). 
      • To make the problem crystal clear: where this double pattern presents the biggest problem is in searching a space for potentially "broken" link bodies (aka anchor text aka link text) after renaming a page. You are forcing us to do 2x the amount of searches. One search for the CDATA format of the link body. A second search for the PCDATA format of the link body. Because we won't necessarily know which format was used under the covers, do we?. And before you say "why not just search for the link body string in the rendered RTE text of the page?", please stop and think: do you really want your users to be forced to wade through potentially hundreds of search hits (search string in any possible context) or to wade through only dozens of search hits (search string only in context of a link body)?
      • The only place you should force a CDATA syntax on your users is inside of {code} and {noformat} macros.
    • When is the "global search field supports searching for storage format syntax" coming? Your product is still wholly unusable until this feature is back in place.
    • Lists: do you support the disc bullet item type? If so, please add that to the syntax reference above.
    • Do you support <b> and <i> as alternatives to <strong> and <em>? This is a prime example of what I mean when I have complained about your facile statement that "our storage format is just XHMTL with some stuff tacked on to handle our macros. (If you would just publish your XSD or DTD, we wouldn't have to ask questions like this. If you would just publish a proper language reference, we wouldn't have to ask questions like this.) If you support <b> and <i>, please add that to the syntax reference above.
    • NOT NEARLY ENOUGH DETAIL for the {toc} macro. omgwtfbbq? Where are the syntax details for include/exclude or all the other myriad parameters for that macro? Do you realize how much at least some of your customers depend on really specific include/exclude tricks to get {toc} to do all manner of very useful stuff? This is another example of what I mean when I complain LOUDLY that this "just a few examples" approach to your syntax language reference is simply not good enough. Why the frak should we need to ask questions like this?
    • Where are the {children} macro details? Like {toc}, {children} is a critical, often-used macro. Of all your macros, I use {toc} and {children} the most.  Again, why the frak should I even have to spend time asking questions like these? 
    • In general, your macro documentation is woefully lacking. I have no idea what my options are when it comes to nearly all of your macros. A handful of  examples simply does not suffice. You have no idea how angry I am right now because of this. You are effectively forcing me to deal with a data migration to some other wiki engine because you guys are too freaking lazy to properly document your own syntax that you shoved down our throats. I've wanted to give the Confluence team the benefit of the doubt because I know firsthand what a tough job it is to execute a major architectural change. But honestly, this is crazy bad architectural design and crazy bad documentation support. You didn't start with a rigorous XSD/DTD-based approach to your design and implementation and validation/parsing, and because of that, you're generating tons of new technical debt for yourselves AND you cannot properly support your user base with even the most basic information they need. FAIL.
    1. And let me be perfectly clear on one fundamental point: I can live with the loss of wiki syntax, and I can force/educate/support/cajole the other users in my enterprise to live with the loss as well. But what I cannot live with is an undocumented syntax or a poorly-documented syntax. I cannot support my internal user base if they come to me with "how-to" questions or problems I need to debug if you refuse to give me the information I freaking need.

      I'm serious. This fundmental flaw in your user support alone will force me to turn my back on you guys forever and deal with the headache of migrating to another wiki engine. If you would just do it right, I could argue successfully to the other stakeholders that we should stick with Confluence.

      I'm not short-sighted like some other posters/complainers here have been. They have legitimate complaints about the loss of wiki syntax, but there is a cost to migrating to a different engine and IMO that cost is not worth it only to gain back a wiki markdown syntax. But the cost IS worth it if staying with Confluence means working in an effectively undocumented environment with every troubleshooting operation requiring a user to freaking reverse-engineer your code because you guys are too lazy to document it for the users.

      1. And one more thing: how hard can it be, really, to just document all your macro syntax fully?

        • You don't have that many core Atlassian-produced macros
        • You already know the older wiki macro syntax so you know exactly what questions to ask your dev SMEs

        Any of my agile teams, past or present, could do this in the span of a single 2-week sprint with only one single tech writer and a couple hours (max) from 2-3 dev SMEs at most. We're talking a measly 5-point story here. Why won't you just get this done already and shut me the heck up, lol

    2. We haven't finalised the doc - The intention was to remove the completed items and provide more helpful information to users like who can view and edit the source and how they do it.

      1. Then why did you remove the table of "to be done" stuff that was at the top of this page? Its removal and the current intro to this page sure makes it seem to me like "you're done and you've finalized this content". Regardless, your comment immediately above then begs the question: When is the rest of the complete doc coming? As I've mentioned several times, it's not worth even testing your new advanced editor until you have proper doc for it.

  14. Still waiting for some statement from Atlassian regarding when and if you plan to actually deliver meaningful, complete documentation on all your macro elements.

  15. Anonymous

    You have a crappy bug in your source editor. Why do hyperlinks with underscore characters not show up in source editor?

    The hyperlink looks like this: <a href="http://download.java.net/media/jai/builds/release/1 1 3/">

    But the hyperlink is this: <a href="http://download.java.net/media/jai/builds/release/1_1_3/">

    Why is this?

     

    1. Which version of the plugin are you using? I've filed a bug for you here... SOURCE-59 - Getting issue details... STATUS

  16. Rudimentary validation of Confluence XML using a customized XHTML 1.0 Strict DTD

    I took a few hours today to:

    1. Create a rudimentary DTD for the Confluence storage format, based on the XHTML 1.0 Strict DTD. (Why a DTD and not a schema? To save time. Before today, I had not done any real editing of DTDs for years; it's all been schemas. Even so, doing the same thing with a schema would have taken me longer.)
    2. Validate the XML source of a small set of pages (a few hundred) in a test "sandbox" installation of Confluence 4.

    I have documented what I have done as a step-by-step procedure (using wording such as "Copy...", rather than "I copied..."). Sorry, these steps are not formatted as an ordered list (I do not yet feel adept enough with the new editor to attempt this).

    Create a rudimentary Confluence DTD

    Download xhtml1-strict.dtd and its three xhtml1-*.ent files (lat1, special, and symbol) from the W3C website.

    Create a copy of xhtml1-strict.dtd and name it confluence.dtd.

    Replace the references to the three xhtml1-*.ent files with the actual file contents, so that confluence.dtd is standalone. (This step is not strictly necessary, or even desirable; I did this for expediency.)

    Create an entity that lists all top-level proprietary Confluence elements ("top-level", as in, proprietary Confluence elements that are not necessarily always nested inside another proprietary Confluence element). Add the following line near the top of confluence.dtd (just below the comment header):

    <!ENTITY % ac "ac:macro | ac:link | ac:emoticon | ac:image | ri:page | ri:blog-post | ri:attachment | ri:url | ri:shortcut | ri:user | ri:space | ri:content-entity">

    Allow all top-level proprietary Confluence elements as inline, block, and flow elements. (I did say this was a rudimentary DTD; I don't want to spend too much time guessing undefined rules!) Add a reference to the ac entity to the following existing lines:

    <!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline; | %ac;)*">
    <!ENTITY % Block "(%block; | form | %misc; | %ac;)*">
    <!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc; | %ac;)*">

    Add xmlns:ac and xmlns:ri attributes to the attribute list of the html element:

    <!ATTLIST html
      %i18n;
      id          ID             #IMPLIED
      xmlns       %URI;          #FIXED 'http://www.w3.org/1999/xhtml'
      xmlns:ac    %URI;          #IMPLIED
      xmlns:ri    %URI;          #IMPLIED
      >

    Declare the proprietary Confluence elements and their attributes. Add the following lines to the bottom of confluence.dtd:

    <!-- Atlassian Confluence -->
    <!ELEMENT ac:macro ANY>
    <!ATTLIST ac:macro
    ac:name     CDATA          #IMPLIED
      >
    <!ELEMENT ac:rich-text-body ANY>
    <!ATTLIST ac:rich-text-body
    ac:name     CDATA          #IMPLIED
      >
    <!ELEMENT ac:plain-text-body ANY>
    <!ATTLIST ac:plain-text-body
    ac:name     CDATA          #IMPLIED
      >
    <!ELEMENT ac:default-parameter ANY>
    <!ELEMENT ac:parameter ANY>
    <!ATTLIST ac:parameter
    ac:name     CDATA          #IMPLIED
      >
    <!ELEMENT ac:image ANY>
    <!ATTLIST ac:image
    ac:border   CDATA          #IMPLIED
    ac:height   CDATA          #IMPLIED
    ac:width    CDATA          #IMPLIED
    ac:align    CDATA          #IMPLIED
      >
    <!ELEMENT ac:link ANY>
    <!ELEMENT ac:link-body ANY>
    <!ELEMENT ac:emoticon ANY>
    <!ATTLIST ac:emoticon
    ac:name     CDATA          #IMPLIED
      >
    <!ELEMENT ri:page ANY>
    <!ATTLIST ri:page
    ri:content-title CDATA     #IMPLIED
    ri:space-key     CDATA     #IMPLIED
      >
    <!ELEMENT ri:blog-post ANY>
    <!ATTLIST ri:blog-post
    ri:content-title CDATA     #IMPLIED
    ri:posting-day   CDATA     #IMPLIED
      >
    <!ELEMENT ri:attachment ANY>
    <!ATTLIST ri:attachment
    ri:filename CDATA          #IMPLIED
      >
    <!ELEMENT ri:url ANY>
    <!ELEMENT ri:shortcut ANY>
    <!ELEMENT ri:user ANY>
    <!ATTLIST ri:user
    ri:username CDATA          #IMPLIED
      >
    <!ELEMENT ri:space ANY>
    <!ELEMENT ri:content-entity ANY>

    Note the use of ANY in these element declarations. I have, so far, deliberately made no attempt whatsoever to define which elements are allowed inside each proprietary Confluence element. This is a major shortcoming. For example, this DTD will currently allow anything - potentially monstrous markup - inside ac:rich-text-body. I might look into fixing that later.

    I did not add these declarations all at once. It was an iterative process. Each time the validation process (described below) reported an error for an undefined element or attribute, I went back and added the missing declarations to the DTD.

    I do not claim that this is a comprehensive declaration of proprietary Confluence elements. In fact, I doubt that it is complete. I do not even claim that it is complete with regard to the source format documentation provided by Atlassian. All I have done is to add to my copy of the DTD the proprietary Confluence elements and attributes that occur in a small set of pages (a few hundred) on a test "sandbox" installation of Confluence 4.

    If you follow this procedure using your own files, I expect that you will meet proprietary Confluence elements and attributes not covered in the declarations listed here. You will need to do as I did, and iteratively add to these declarations, whittling down the validation errors.

    Get your Confluence XML source files

    Use the free wget tool to get all .txt files from Confluence 4:

    "C:\Program Files (x86)\GnuWin32\bin\wget.exe" --user=usr01 --password=pa55w0rd -r --no-directories -A.txt http://server:8090/plugins/servlet/confluence/default/

    (Does this method of access require the Confluence WebDAV plugin? I do not know. This particular Confluence server does have the WebDAV plugin installed.)

    Curiously, many of the .txt files had 0 length. I'm going to leave that mystery for another day.

    Note that the --no-directories option causes wget to save all files to the current directory, without creating subdirectories.

    Prepare the source for validation

    Write a script (I used VBScript) to:

    1. Delete .txt files that are actually plain text files (for example, plain-text attachments to Confluence pages), rather than .txt files that contain the XML source for Confluence pages. (My script sniffs the first character in the file: if it's a <, I keep it. Yes, risibly fallible and simplistic.)
    2. Wrap the contents of the other (XML source) .txt files in the following markup, and then save the wrappered content in .xml files (and delete the original .txt files):
    <!DOCTYPE html SYSTEM "confluence.dtd">
    <html xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier">
    <head>
    <title>Title</title>
    </head>
    <body>

    insert .txt file contents here

    </body>
    </html>

    Confluence serves the source of a page as a .txt file containing an XML snippet - the contents of a <body> element, as displayed in the Source Editor plugin - rather than a complete XML document, hence the need to add this wrapper.

    Validate the source

    Copy confluence.dtd to the directory containing the .xml files.

    Write a Windows batch file that uses the free xmllint tool to validate the .xml files.

    Here's the heart of the batch file:

    for %%f in ("*.xml") do "%_xmllint%" --noout --valid --loaddtd "%%f"

    where the temporary environment variable _xmllint contains the path of xmllint (for example, set _xmllint=%cd%\libxml2\bin\xmllint)

    Results

    I did this largely because I was curious to see, after clearing away the issue of validating the proprietary Confluence markup (I will freely admit, in a risibly rudimentary fashion!), whether the non-proprietary markup (inherited from the original XHTML DTD) in my sample Confluence 4 pages was valid. As I mentioned in a previous comment on this page, I feared that, because Atlassian had not been using a schema to validate the source, Confluence 4 might be creating/allowing invalid XHTML structures (independent of any issues to do with the proprietary Confluence markup).

    Of the few hundred pages I tested, I found only one such issue. One of the files contained the following invalid markup:

    <ul> </ul>

    That is, a <ul> without any <li> child elements.

    So, as I suspected, Confluence 4 does indeed allow/create invalid XHTML, but I'm pleasantly surprised and relieved that I did not find more issues. I'm not completely relaxed about this subject, though, because I think that the majority of pages that I have tested have been migrated from Confluence 3.x without much subsequent editing in Confluence 4. At least now, though, I have a relatively automated method for detecting these issues. I can begin to validate Confluence 4 XML source.

    1. I should mention that I hated hardcoding the ac: and ri: namespace prefixes in the DTD. Please feel free to show me how to avoid this. I'm more familiar using XML schemas, where namespace prefixes can differ between the XML schema and XML instances, and also between XML instances (for example, soap: or soapenv: ); it's the namespace URI that must remain constant.

      1. Re:

        I should mention that I hated hardcoding the ac: and ri: namespace prefixes in the DTD.

        I've just seen some documentation on the W3C site that describes a workaround for this. In brief, if the DTD uses an entity for the namespace prefix, then the DTD subset of an XML instance can redefine that entity (binding that namespace to a different prefix). This is verging on academic, because I don't anticipate Confluence page source using anything other than the namespace prefixes documented by Atlassian (currently, ac: and ri: - an aside, perhaps a non sequitur to some readers: I'm starting to dislike those autocomplete emoticons in the rich text editor!), but it's good to know in case it's ever an issue.

         

        1. ...unfortunately, it turns out not to be that simple, because each namespace-qualified element type declaration and attribute type declaration in the DTD needs to be adjusted to use the entity.

          The following is not enough:

          <!ENTITY % xmlns.ac.prefix "ac">
          <!ELEMENT %xmlns.ac.prefix;:macro ...

          You need to wrap the entire element name in its own entity, and refer to that entity in the element type declaration (and, I guess, everywhere else the element name is referenced):

          <!ENTITY % ac.macro.element "%xmlns.ac.prefix;:macro">
          <!ELEMENT %ac.macro.element; ...

          I'm not sure I want to go to that effort right now. For now, to keep it simple, I'll leave these namespace prefixes hardcoded in the DTD.

    2. First off, Graham, thanks for this exercise and taking the time to post it here.  BTW DTDs are so much easier to read and parse as a human than XSDs, IMO, but that's a matter of personal preference I guess.

      Why you're my hero (smile) : Your post very tellingly proves two points I've been trying to make to the Atlassian PMs, architects, and tech writers for nearly 4 months straight:

      1. Graham spent only "a few hours" to get this far. To move one step closer to providing a tool needed to validate the underlying XML storage format using third party editors, or in 3rd party systems involved in a more elaborate publishing workflow. So why the hell couldn't Atlassian have prioritized producing a XSD or DTD artifact for the community much higher on their backlog already? It's been 4 months since we started asking for this and explaining in great detail not only how much value it would provide, but why it's essentially mandatory to provide.
         
      2. Notice how Graham says: "Note the use of ANY in these (ac: and ri:) element declarations. I have, so far, deliberately made no attempt whatsoever to define which elements are allowed inside each proprietary Confluence element. This is a major shortcoming."

        • Yes, exactly. It's a major shortcoming. How many times do I have to practically beg you guys to just pony up and document your damn macros already? We cannot guess at these hidden details that only you know. It is imperative that you document the XML syntax for all of your macros ASAP. You cannot seriously expect us to take the meager documentation you have provided so far and actually experiment and reverse engineer the content model for your macros, can you? Really? What are you guys smoking over there? How can this not be a high-priority story for your backlog? 


      One other thing: why is it that your 4.2beta space now requires us to enter a Captcha-style challenge phrase to post comments here when we're already logged in and authenticated? Please turn that off. Your comment challenges are annoying as hell because you do not provide any control to generate new phrases when the existing one is unreadable. I seriously hate captcha-style challenges. 8 out of 10 are literally unreadable to me. Oh wait, I understand now: you're trying to actively discourage feedback. (wink)

      1. How many times do I have to practically beg you guys to just pony up and document your damn macros already?

        Exactly to what level do you wan't them to do this and where? Given an example?...

        If i read you right then i deeply disagree and I don't think that is what Graham had in mind when he wrote what he did, but before I get into that I would like you to go deeper into what it is your looking for, and maybe give an example from say the code macro?... Before I make a huge rant on why this is a bad thing, I wan't to know what your meaning of "macro" is.

        ac:link | ac:emoticon | ac:image | ri:page | ri:blog-post | ri:attachment | ri:url | ri:shortcut | ri:user | ri:space | ri:content-entity

        These are not considered to be under the term "Macro" in my eyes, they are Confluence specific Elements. They might behind the scene behave much like so, but that is an Implementation detail hidden to us.

        Keep in mind that macros are plugins which means:

        • Macro version may not correspond with the Confluence version it was released with, as macros can be updated separately (for Macros shipped with Confluence)
        • Macros may change more frequently in a Confluence installation
        • 3rd party Macros may be unknown to Atlassian
        • The sum of macros will be highly likely to be different to the thousands.

        That Macros should be documented, also with how they look in the storage format, I don't disagree on, that should just be done under the documentation for that specific macro.

        1. Jens, you merely have to look at my various comments further up in this same thread to see examples of specifically what I mean, and why I feel they're necessary. Of course I'm not asking Atlassian to document all possible 3rd party macros. I'm asking only that they document their own macros.

          The most recent set of arguments are in this particular comment (above) and its immediately following sub-comment:  This comment

          (And for frik's sake, I'm on my 6th fraking attempt to type the goddamn challenge string for this stupid comment. Please turn this OFF for authenticated users!)

          1. None of the above is a clear answer to what I wish a 100% clear answer to, they can all to some degree be interpreted.

            Now what I hear you saying is that you wan't this page to include the following 2 things?

            1. A documentation that includes as an example for the Code macro:

              Parameters

              A list of named parameters for the code macro, like:

              • lang
              • title
              • collapsible
              • etc.
              Values

              Possible Values for the code macro Parameters, like for lang:

              • csharp
              • java
              • xml
              • etc.
            2. I also hear you as you wan't that to be present in a DTD or XSD???...


            First things first...

            1. Documenting Parameters

            Documenting parameters and their values can't be done here, well it can but it would "break" the documentation by the nature of macros.

            Basically because ones you update your macro without updating your confluence installation, you will lead your users to the wrong documentation for that macro.

            Imagine that breaking changes had been implemented, suddenly what the users read as correct use of the macro will break a confluence page (or well that part of the page).

            That is why documentation of Macros MUST be with the macros and not the Confluence Storage format, so under the documentation for the code macro, there should be a section explaining the above and give examples of how to type that in the storage format, but the documentation already here is already damaging to that scenario.

            2. Include Macro Parameter Validation in XSD or DTD

            Doing that has so many complications.

            Firstly if we add this to the validation of what we post back to confluence, you makes it harder for us to migrate confluence content. (under the assumption that the API would reject the same thing, but if not then whats the whole point?). What about migrating data from Installation X that has 20 deployed macros in use to Installation Y that has 15 deployed macros?

            It also raises questions about upgrading macros that introduce breaking changes in a confluence installation. 

            But it also enforces me to ever so often make sure that I have the right DTD or XSD with me, so I need to keep updating that.

            No thank you from here, I would much rather have a Stable DTD or XSD that did not change regardless of deployed macros or their versions...

            That is what I heard you say, and how I read your comments through out this thread... But I wanted to make sure that I was not mistaken, however, that was not something you wanted to clarify on. 

            1. Jens, respectfully, please stop and think for a moment about how the macros were documented before in the wiki markup syntax.

              1. Go find a 3.5.x or lower instance of Confluence somewhere.
              2. In that instance, edit a page and make sure you're in the Wiki Markup view.
              3. Take a look at the big Help Tips panel at the right of the editor box.
              4. Look carefully at the Full notation guide link at the bottom of that Help Tips panel.
              5. Click that link and tell me what you see? Do you not see a list of all the macros and all the syntax for the various arguments for each macro?

              Please tell me where the corresponding and equivalent documentation for these same core macros produced and maintained by Atlassian exist in the new 4.0 environment specifically for when you are debugging problems with a page in the new advanced editor.

              The answer is: right now no such equivalent detailed doc exists. All we have are a few woeful examples up in the core content of this very page.

              Respectfully, I will engage you no more on this. My intent is clear and my explanations are clear. Until such equivalent documentation exists for the XML format, the new advanced editor is largely unusable.

              1. Respectfully? how about Disrespectfully?... I know very well how it was done in 3.5, my private Confluence server is still running that version. Thank you very much.

                I was trying to get things cleared up, so I could either Agree or Disagree, because you choose not to clear things up, I made an interpretation based on the context you wrote your responses, chances are that others might draw the same conclusions. It might be a misinterpretation?... Well you haven't cleared that up yet so how do we know?... Instead you dive into something that looks like an attack. Now that tells me more about you than anything else I needed to know.

                Now it has been fairly clear to me that you wanted the validation of each individual type of macro to go as deep as values, parameters and attribures, but on the off chance that I was mistaked, i wanted to give you the chance to clear that up before I gave my opposition towards it.

                My suggestions stands:

                • Document the Macros and corresponding storage format on pages dedicated for them individually. NOT HERE

                • Keep the DTD or XSD free of details on specific macro's and instead general to the overall structure all macros must conform to:

                  //Outer structure: name required but it does not have to exist to mitigate migration of confluence content from one instance to another where the same plugins are not yet installed.
                  <ac:macro ac:name="code"> 
                      //Inner structure: 0..N Parameters, name required, no validation against if the macro accepts this or not to mitigate changes between plugin versions as well as data migration as above.
                      <ac:parameter ac:name="title">This is my title</ac:parameter>
                      <ac:parameter ac:name="linenumbers">true</ac:parameter>
                      <ac:parameter ac:name="language">html/xml</ac:parameter>
                      //Inner structure: Plan-text-body, required or not???... I suppose not all macros would need one. But I would guess that the <ac:macro> tag would only allow for 1, so it is either A 0..1 or 1..1.
                      <ac:plain-text-body><![CDATA[this is my code]]></ac:plain-text-body>
                  </ac:macro>

                  (if that is the structure)
                  And from that point, treat the macros as isolated black-boxes (Plugins 101 for me)

                • Provide the means for the Plugin developers, AT FREE WILL to provide documentation that can be integrated into confluence help (as stated in another response in this page)

                • Shut up about it already, they have heard you... I don't think it helps a single person repeating him self over and over again, gather support instead, be constructive instead of just "you must provide documentation, this is not good enough"... Graham was constructive.

                1. I used the word "respectfully" and nothing else. I'm sorry you choose to read antagonistic meaning into that, but that's a limitation of this communication medium and beyond my control.

                  I was essentially trying to not belabor the point by debating with you pros and cons here: Atlassian can see my suggestions/requests, yours, Graham's and everyone else's, and they can deal with how to best deal with all the user feedback. If I go back and forth with you forever, it simply dilutes both of our "messages", which aren't really as different as you seem to think.

                  So in an attempt to "not dilute the message" any more than necessary, regarding your specific contentions:

                  • I don't disagree with the spirit of what you say. Nor do I disagree with many of the particulars.
                  • My main point is to simply have the documentation about all the syntax for all the macro arguments one way or another. I don't care too much about the specific format of the doc. What I don't want, however, is zero doc, which is what we have right now.
                  • Again, I'm not talking about any third party macros. I rarely use them (too much risk, generally, in relying on 3rd party stuff to flesh out the core system). All I'm talking about are the core macros that come with Confluence. Yes, 3rd party devs should do the right thing and doc their macros too, but I'm not talking to them here; I'm talking to Atlassian.

                  Now with the foregoing in mind, I will say that I don't see it as anything more than a small amount of extra work to aggregate all the macro syntax into one page. I don't care where it's sourced. Confluence supports transclusions, so it should be relatively easy to provide a current page that aggregates all the version-specific macro doc into one page. If I'm not mistaken, that's essentially how that Full Notation Guide for the old wiki markup editor is built: it's dynamic. Sure, not all 3rd party macros plugged into it, but all the Confluence stuff and some 3rd party macros did. Atlassian can easily do this for us.

                  And why should they do this for us? For the same exact reason they did it for the old syntax doc: because it's huge PITA to go searching around through different pages/sources for the doc you need when you're staring at a page of wiki markup syntax and trying to figure out what you can add or how to fix something.  In the current Full Notation Guide you can just Ctrl-F for keywords and instantly find the syntax for a macro you're staring at in your page that is broken somehow or not rendering the results you want.

                  I want that same ease of use in the reference doc for the new XML macro syntax. No more; no less.

                  As for your contention about it not being practical to actually validate macro elements in a DTD/XSD? No. Sorry, but I don't buy that either.  Whether it's through a Python script or an Ant build target or myriad build/scripting approaches, you can easily create an XSD or DTD that exactly matches the current set of macros in a user's Confluence instance. Please tell me: what is the use of an XSD that won't actually validate broken ac: and ri: element syntax?

                  • To put that last question into more specific terms: If the XSD you propose, which "black boxes" the specific ac: and ri: descendant content models, will not accurately invalidate a page that will not render correctly (because of some broken syntax inside a macro element), then that XSD is effectively worthless. Why bother jumping through hoops to try and use that XSD for validation if it in fact will validate completely broken pages that will not render correctly?

                  So ya, there's some infrastructure design and build/scripting involved, but you cannot argue that it's impossible to deal with each customer having a slightly different mix of Atlassian-supplied macros. And they should publish their "API" or "best practices" for making 3rd party macros XSD-friendly, so that 3rd party macros can be dynamically added to the instance-specific XSD and the instance-specific doc page for the XML syntax.

                  Yes, I'm sure Atlassian wishes they could just avoid doing all this by treating their XML syntax as "just an implementation detail", but honestly that's complete bullshit. Sorry, but it is. As I keep reiterating, this is XML 101 and it's not optional to document your syntax. You can argue whether it's helpful to provide an XSD for use in 3rd party editors or for integration with other systems, but you cannot argue whether it's optional to roll out a complex syntax with zero reference doc other than a handful of incomplete examples.

                  Again, to put it another way: how far would you have gotten with their original wiki syntax if they'd decided it was optional to document it, and instead they'd provided literally the same degree of syntax doc for their macros as they have above at the top of this page? How far do you think you'd have gotten with Confluence had they taken that approach originally with their wiki syntax?

                  If you look at it that way, then it's a no-brainer that something's seriously amiss with the current state of the syntax doc at the top of this page. It does not matter to me or the other users what hoops their current architecture requires them to jump through to provide that syntax doc. As they're fond of saying themselves: "that's just an implemenation detail". (sardonic expression)

                   

                  1. Atlassian can see my suggestions/requests, yours, Graham's and everyone else's, and they can deal with how to best deal with all the user feedback. If I go back and forth with you forever, it simply dilutes both of our "messages", which aren't really as different as you seem to think.
                    The point of debating it is to come to a consensus of what we all think would be "acceptable", that would help guide them better, this is part of developing software. Sorry if I am damaged by my profession.

                    My main point is to simply have the documentation about all the syntax for all the macro arguments one way or another. I don't care too much about the specific format of the doc. What I don't want, however, is zero doc, which is what we have right now.

                    I Never disagreed with that, I wanted to clear up the "WHERE" because as I understood you, you wanted it here and that made no sense to me as that would effectively cause situation where you where guided to the wrong documentation as a user without knowing so.

                    Putting the documentation on the pages with the individual macros makes sense to me, I just wan't to stress that we need to know that there is a difference in what version Confluence is running and what version the Macro is.

                    After all I could imagine you blow up just as much when you went to the documentation for Conf 4.1, it said that you should specify the "lang" parameter. Which in the mean time was changed in your installed version of that macro, for whatever reason, so you now had to set "syntaxlang" instead.

                    (Very thought up example in this case i know, but never the less).

                    Again, I'm not talking about any third party macros. I rarely use them (too much risk, generally, in relying on 3rd party stuff to flesh out the core system). All I'm talking about are the core macros that come with Confluence. Yes, 3rd party devs should do the right thing and doc their macros too, but I'm not talking to them here; I'm talking to Atlassian.

                    3rd party or not, the same principle should apply to all macros, the 3 c's... Consitency, Consistency, Conistency... it would also help towards making things more simple for us to understand, so that we know how to acquire the documentation and what to watch out for, rather than being in situations where.

                    Doing your internal stuff differently than what you ask of your 3rd party developer, which is just as much to be considered as users, is jumping hoops to me. If often also leads bad implementations of the "interfaces" they need to use to achieve the same thing, basically because it did not have focus.

                    So yes, it would be damn nice if we could get the old "Quick Reference" back inside of confluence. I can TOTALLY agree on that.
                    But that doesn't really change anything from my point... Documentation is still done close to the macro, Atlassian just provides an feature that picks that up and displays it. 

                    Again, to put it another way: how far would you have gotten with their original wiki syntax if they'd decided it was optional to document it, and instead they'd provided literally the same degree of syntax doc for their macros as they have above at the top of this page? How far do you think you'd have gotten with Confluence had they taken that approach originally with their wiki syntax? 

                    Funny question, I think that over the coarse of 3 years of using Confluence, I can count the times I have had that open on one hand... And I never used it as a first "resource", it was always secondary... So quite far I guess the answer is to that.

                    But to hammer something down, I NEVER said they should NOT document things, I simply wanted them in places where there could be no doubt as to weather you had the right or the wrong documentation version in front of you.

                    THEN to all the XSD/DTD talk. 

                    To put that last question into more specific terms: If the XSD you propose, which "black boxes" the specific ac: and ri: descendant content models, will not accurately invalidate a page that will not render correctly (because of some broken syntax inside a macro element), then that XSD is effectively worthless. Why bother jumping through hoops to try and use that XSD for validation if it in fact will validate completely broken pages that will not render correctly?

                    I NEVER said that ac: and ri: elements should not be validated... I said I did not coun't those under the term "Macro"... now they seem to be implemented as such behind all things (to judge from the administration interface), but they added named elements for them, so they are quite different than <ac:macro ac:name="code"> vs. <ac:macro ac:name="toc">... those 2 are the same element to me. they are both of the type "macro"... and the same rules apply to them both.

                    ac:link | ac:emoticon | ac:image | ri:page | ri:blog-post | ri:attachment | ri:url | ri:shortcut | ri:user | ri:space | ri:content-entity

                    These are not considered to be under the term "Macro" in my eyes, they are Confluence specific Elements. They might behind the scene behave much like so, but that is an Implementation detail hidden to us.

                    Make specific note of these comments:

                    //Inner structure: 0..N Parameters, name required, no validation against if the macro accepts this or not to mitigate changes between plugin versions as well as data migration as above.
                    //Inner structure: Plan-text-body, required or not???... I suppose not all macros would need one. But I would guess that the <ac:macro> tag would only allow for 1, so it is either A 0..1 or 1..1. 

                    And so on, point being that whatever is required of the ac:macro before we even begin to look at what macro, should ofc. be validated.

                    What I don't wan't is a validation that says that the below is "invalid":

                    <ac:macro ac:name="code">
                        <ac:parameter ac:name="title">This is my title</ac:parameter>
                        <ac:parameter ac:name="linenumbers">true</ac:parameter>
                        <ac:parameter ac:name="language">html/xml</ac:parameter>
                        <ac:parameter ac:name="uncleBob">Uncle Bob's Cool Message</ac:parameter>
                        <ac:plain-text-body><![CDATA[this is my code]]></ac:plain-text-body>
                    </ac:macro>


                    Now the uncleBob parameter is unknown to the code macro, at least in this version, but the parameter is structured well enough. And in my mind it should pass, because it might be valid where it came from, and where it goes next...

                    A more likely example could be:

                    <ac:macro ac:name="code">
                        <ac:parameter ac:name="title">This is my title</ac:parameter>
                        <ac:parameter ac:name="linenumbers">true</ac:parameter>
                        <ac:parameter ac:name="language">coolScript</ac:parameter>
                        <ac:plain-text-body><![CDATA[this is my code]]></ac:plain-text-body>
                    </ac:macro> 

                    coolScript, a new supported syntax for the code macro in version say 4.2, yet when I bring this back to a 4.1 version... I would still like to be able to save, the next step here would often actually not be to "fix" the macro with another language, it would be to upgrade the macro on the instances I manage, or to request it on those that I don't.

                    This one is invalid however:

                    <ac:macro ac:name="code">
                        <ac:uncleBob></ac:uncleBob>
                        <ac:parameter ac:name="title">This is my title</ac:parameter>
                        <ac:parameter ac:name="linenumbers">true</ac:parameter>
                        <ac:parameter ac:name="language">coolScript</ac:parameter>
                        <ac:plain-text-body><![CDATA[this is my code]]></ac:plain-text-body>
                    </ac:macro> 

                    Now I should maybe stop up here and tell that I frequently copy content between Confluence Instances, and they do not always maintain the same macros, versions of macros, or even same Confluence versions, so there is why I am considering this. And yes this has actually frequently caused "macro errors", even in plain old Wiki syntax (believe it or not)... In some cases I fixed the syntax, others I installed, upgraded or enabled a macro mostly the later, and even in cases i completely ignored it because I knew it would go back to a instance where it worked...

                    That is why I request a more "Stable XSD".
                    However, if I just get the basic one ill be happy, if they create a basic and a full then fine by me, I just hope it won't turn out to be a useless wasted effort, which i fear it will when first all the implications hit, but if the basic one exist along side of it, by all means.

                    (or replace XSD with DTD throught all the above)

                    But now that we are nutty, why not incorporate so that the XSD ensures that you had chosen an actual existing DataSource Resource in your, say SQL macro? The screw without end.

                    Yes, I'm sure Atlassian wishes they could just avoid doing all this by treating their XML syntax as "just an implementation detail", but honestly that's complete bullshit. Sorry, but it is. As I keep reiterating, this is XML 101 and it's not optional to document your syntax. You can argue whether it's helpful to provide an XSD for use in 3rd party editors or for integration with other systems, but you cannot argue whether it's optional to roll out a complex syntax with zero reference doc other than a handful of incomplete examples.

                    Nice extreme twist of my words, completely derailing the point in what i at all said containing the phrase "implementation detail"...

                    And with that I am done... 

      2. (You're welcome, Shannon.)

        I agree wholeheartedly with Shannon's comment:

        We cannot guess at these hidden details that only you [Atlassian] know. ... You cannot seriously expect us to ... reverse engineer

        I could take the DTD some way further on my own, but I'm already reverse engineering. For example, I'm only guessing that you intended your XML source to be interpreted as the contents of an XHTML body element. And I have no way of knowing which, if any, XHTML structures I should remove from confluence.dtd.

        I'd be curious to use this validation technique - or see the results - on a larger set of source files that have been created, or at least updated, in Confluence 4. I'm not sure what the protocol is for exchanging contact details here, but I'm using my real name, and I'm not difficult to find: understandably, users might be reluctant to send me a wget-extracted .zip of their corporate wiki source (chock-full of confidential intellectual property), so I'm happy to assist anyone interested in validating their source as I've done, mainly just to check that Confluence is being well-behaved with non-proprietary XHTML markup. That includes updating my rudimentary DTD for any new proprietary Confluence markup that crops up. I'm not interested in your content: I just want to know about any validation errors in the XHTML.

         

  17. I also forgot to mention: you can edit the resulting XML files (described in my earlier long comment) in a validating XML editor (for example, jEdit with XML plugin).

    So, if you're using the Confluence Source Editor plugin, but you'd rather be using a validating XML editor, you could copy'n'paste the XML source displayed by the plugin into the wrapper I described earlier (here it is again):

    <!DOCTYPE html SYSTEM "confluence.dtd">
    <html xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier">
    <head>
    <title>Title</title>
    </head>
    <body>

    insert XML from Source Editor plugin here

    </body>
    </html>

    and then (with confluence.dtd in the same directory) edit the source in your favorite validating XML editor, before copying'n'pasting the contents of the <body> element back into the Confluence Source Editor. Ideal? Far from it. But at least you'll enjoy the benefits of a proper XML-aware editor (not just validation, but type ahead/autocomplete/selection lists, structure browsers etc.).

    It wouldn't take too much to write some (perhaps, editor-specific) "glue" script/code to automate the getting/wrapping/unwrapping of the source, to make the process a little less cumbersome.

  18. ++ to what Shannon Greywalker, Graham Hannington, and others like Todd Day, Greg Whitfield,  Kathleen James, et al. have been saying.

    I admire the civility and constructiveness of your criticism, as well as your willingness to share your technical knowledge.

    I feel like you represent my position well, so have not felt the need to weigh in up to this point.

    Thank you for your persistence and the amount of detail you guys have gone into.

    Some summary points from discussion on these pages:

    • Editing content is more common than creating new content.
    • Without wiki markup, there is no EASY way to work around bugs in the RTE, which are somewhat of an inevitability for all RTEs.
    • The Source Editor does not appear to be attempting to replicate the ease of use available through wiki markup as source.

     

  19. Hallo everyone

    Our sincere apologies for having to turn on the CAPTCHA validation on comments by logged-in users. I know it's a total pain. We've had to do it because this site has been receiving a huge number of spam comments recently, making some pages unreadable. The spam comments are obviously auto-generated, and contain long strings of text, links to various vendors sites, pictures and what have you. We investigated a number of options, including disabling the remote API in case the comments were coming in on that route. But alas, it seems that someone has written a routine that hits the UI and bombards it with comments. They use the "Sign Up" link to create a username first, and Confluence therefore sees them as legitimate logged-in users.

    Our only resort is to enable CAPTCHA for logged-in users, across the entire site. We are able to identify certain groups, including the licensed community authors and Atlassian staff, who therefore do not see the CAPTCHA request. But unfortunately everyone else is affected, until we can think of another solution.

    Cheers, Sarah

  20. Dear Atlassian,

    Regarding my earlier comment:

    I'd be curious to use this validation technique - or see the results - on a larger set of source files that have been created, or at least updated, in Confluence 4.

    Could you please email me, or make available via, say, FTP or HTTP download, a .zip of the XML storage format of as many of your public Confluence 4-sourced pages as you like? (If the .zip is bigger than, say, 10MB, then FTP or HTTP download would suit me better than an email attachment.)

    If there's some automated method that I can use to scrape the XML storage format of your public pages myself, please let me know, and I'll do that instead. (I've tried pointing wget - as per the method I used with my local sandbox installation, described in that earlier comment - at your public sites, but either I'm using the wrong path, or those sites deliberately do not offer this method of access.)

    I know that the simplistic DTD I've created does not fully cover the Confluence markup that you've documented (ac:image attributes spring to mind), only the markup that exists in my small set of "sandbox" files. A set of Confluence XML source files that uses a wider range of the possible markup would help me to more quickly refine the DTD. I think the resulting improved DTD might be of benefit to some users. I'm happy to send you the subsequent refined DTD (or even the current rudimentary version) if you think it might be useful as, perhaps, an attachment to CONF-24884 - Getting issue details... STATUS , as a temporary "placeholder" until you develop a (better, more accurate; definitive) DTD/schema. Let me know.

    I'm working on an XSD version, too (which will probably refer to - import - the original XHTML1 Strict XSD untouched, redefining some of its groups to included proprietary Confluence markup, rather than being an edited version of that original XSD... at least, that's my current plan). Can't promise when, though.

  21. I don't want anyone to think that I consider the html/body wrapper (presented in earlier comments) to be optimal. It's just an expedient way of getting Confluence page source to validate using a minimally customized XHTML DTD.

    Probably a more appropriate wrapper - the source needs some kind of a wrapper; otherwise, it has no single root element,
    making it at best a snippet, rather than an XML document - would be something like:

    <!DOCTYPE ac:confluence SYSTEM "confluence.dtd">
    <ac:confluence xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier" xmlns="http://www.w3.org/1999/xhtml">
    insert XML from Source Editor plugin here
    </ac:confluence>

    which would require further customization of the DTD, to declare the newly coined ac:confluence root element and allow it to have the same dependent elements as an XHTML body element. I haven't done this yet.

    Perhaps the root element name should be something like ac:page instead of ac:confluence... I tend to think that the namespace should provide the "Confluence" context, leaving the root element name to describe its contents within that context, such as a "page", but I feel that I'm just working on a stop-gap temporary solution (in the space that I hope Atlassian will soon fill), so I'm not going to spend too much time right now thinking about such choices. Same goes for the "atlassian.confluence" and "resource.identifier" namespace URIs; these are intended as temporary values only. I welcome suggestions.

    One advantage of the html/body wrapper is that, if you give the file an extension that your web browser recognizes as being HTML (or XHTML), such as .html or .htm, then you can do a rudimentary preview by opening the file directly in your web browser (in which case, you might want to add a reference to your Confluence CSS). But your browser won't do much with the proprietary Confluence elements.

    Perhaps a smarter approach would be to use the ac:confluence or ac:page (or whatever) root element, save as .xml, and insert a reference to an XSLT stylesheet, like this:

    <?xml-stylesheet type="text/xsl" href="confluence-to-xhtml.xsl"?>

    When you open the .xml file in your browser, the XSLT would transform/expand the root element into html, head, body, etc., and also transform the various ac:* and ri:* elements so that they stand out clearly among the formatted XHTML. Or you could write XSLT for some of the ac:* and ri:* elements to emulate their behavior in Confluence (some would be easy, some would be harder, and some - because, for example, they rely on information from elsewhere, such as inside Confluence - are probably best left to Confluence itself... adding such "preview" smarts is not high on my list of priorities).

  22. Atlassian, you've so far made no comment on various references I've made to the subject of which, if any, elements and attributes should be removed from the XHTML schema when creating a schema for the Confluence storage format.

    Let's look at an example.

    Edit a Confluence page, and open the source in the Source Editor plugin.

    Insert an XHTML definition list. For example:

    <dl>
    <dt>Term 1</dt>
    <dd>Definition 1</dd>
    <dt>Term 2</dt>
    <dd>Definition 2</dd>
    </dl>

    Click Apply to close the Source Editor plugin and return to the RTE.

    The definition list appears, and you can edit its contents, but now save the page. The definition list disappears.

    Edit the page again, and open the source in the Source Editor plugin. It shows an empty definition list element, <dl/>.

    This is just one example. I imagine there are probably many other similar examples.

    What subset of XHTML does Confluence support?

    I imagine your answer might be something like "The subset of descendants of the XHTML body element that can be created using the RTE". In which case: could you please be specific? I'd prefer not to have to guess/work this out for myself.

    1. Anonymous

      Further to my "What subset...?" question, I took a few minutes to exercise all of the options (that I thought would generate XHTML markup, rather than proprietary Confluence markup) in the rich text editor toolbar, in an attempt to begin to answer that question myself. Here's the source copied from the Source Editor plugin:

      <p>Paragraph</p>
      <p style="margin-left: 30.0px;">Indent</p>
      <p style="text-align: left;">Align left</p>
      <p style="text-align: center;">Align center</p>
      <p style="text-align: right;">Align right</p>
      <h1>Heading 1</h1>
      <p>-</p>
      <h6>Heading 6</h6>
      <pre>Preformatted</pre>
      <blockquote>
        <p>Quote</p>
      </blockquote>
      <p>
        <strong>Bold</strong> <em>Italic</em> <u>Underline</u> <span style="color: rgb(255,0,0);">Colour</span> <s>Superscript</s> <sub>Subscript</sub> <code>Monospace</code>
      </p>
      <ul>
        <li>Bullet list</li>
      </ul>
      <ol>
        <li>Numbered list</li>
      </ol>
      <p>
        <a href="http://www.google.com/">Link</a>
      </p>
      <table>
        <tbody>
          <tr>
            <th>Column heading 1</th>
            <th>Column heading 2</th>
          </tr>
          <tr>
            <td rowspan="2">Cell 1</td>
            <td class="highlight">Cell 2</td>
          </tr>
          <tr>
            <td class="highlight" colspan="1">&nbsp;</td>
          </tr>
        </tbody>
      </table>
      <p>&nbsp;</p>
      <hr/>
      <p>&nbsp;</p>
      <p>Line<br/>
       break</p>

      In a more compact form, in no particular order:

      • p
      • h1 - h6
      • blockquote p
      • strong
      • em
      • u
      • span
      • s
      • sub
      • code
      • ul li
      • ol li
      • a
      • table tbody tr th/td
      • hr
      • br

      The code listing shows attributes; this compact list only shows elements (or specific element structures). By listing the span element, I do not mean to imply that you can use the RTE to insert any span element that would be valid according to the XHTML schema. As far as I can tell, the only span element that you can insert using the RTE is to apply colour (that is, a span element with the specific pattern of style attribute shown in the code listing).

      Nothing much new here: this experiment really only corroborates the documentation already in the body of this page (except for class="highlight").

      (I'm deliberately omitting mentioning supported entity references - such as &nbsp; - for now. Just elements and attributes.)

      I can't see how, in the RTE toolbar, to set an unordered list to use square bullets. I can, however, use the Source Editor plugin to add a style="list-style-type: square;" attribute to the <ul> element, and that works; what's more, that style attribute remains intact when I save the page (unlike the contents of the <dl> element I described in an earlier comment!).

      So, although I think I have a fair idea of what XHTML the RTE can create, which additional XHTML elements and attributes are supported (by which I mean, more or less: will be tolerated by the RTE if you add them in the Source Editor plugin) is not clear to me. For example: style attributes on <ul> elements, yes; descendant elements of <dl> elements, no. So I still don't have a clear idea of which, if any, XHTML elements and attributes to omit from the schema, so that users editing Confluence source in external XML editors do not inadvertently introduce XHTML markup that is not supported by Confluence, in the sense that the markup will, as per the <dl> example, disappear when you save the page, or, perhaps, be garbled.

      Atlassian, any comments/thoughts on any of this?

    2. What subset of XHTML does Confluence support?

      Hi, Graham. The documentation in this page is already comprehensive - Any tags you don't already see documented on this page will likely get removed when you save the page. I've filed an issue for this particular example.  SOURCE-60 - Getting issue details... STATUS

      1. The documentation on this page is anything but comprehensive. Since you do not fully document your macros, citing only a few paltry example, it's perfectly logical for someone to assume that everything else you have here is just a sampling of your entire (undocumented) syntax. To further prove that such an assumption is logical, on March 25, you (Bill Arconati) said:

        We haven't finalised the doc - The intention was to remove the completed items and provide more helpful information to users like who can view and edit the source and how they do it.

        Finally, for any other interested onlookers, be aware that in a separate email exchange between me and Scott Farquhar very recently, he effectively said "Do not expect us to fully document all of our macros". So there you have it: what's above on this page is likely the only support you'll have for the storage format syntax until a lot more of you add your voices to the choir. Obviously they don't want to hear my arguments anymore.

      2. Thanks for the reply, Bill.

        Regarding your statement:

        The documentation in this page is already comprehensive - Any tags you don't already see documented on this page will likely get removed when you save the page.

        When you write "any tags", are you also implicitly referring to "any attributes of those tags"? Is the documentation in this page comprehensive for attributes, too? That is, no attributes on any elements, except as shown in this page? I do not see any documentation for the use of the style attribute for indenting and aligning p elements, except as demonstrated in a code listing (generated by the rich text editor) in one of my earlier comments. Or the class="highlight" attribute in tables. Or the class="atl-forced-newline" attribute on br elements.

        In reference to my recent comment about nesting p elements inside li elements (a structure that is allowed in XHTML), could you please point me to where this page documents the contexts in which the p element is allowed? I cannot find that information - or similar information for other elements - on this page. I have had to work that out for myself by using the rich text editor and inspecting the resulting source. Or do you consider documentation for an XML vocabulary to be comprehensive if it lists the tags (elements; and, perhaps, their attributes) that can be used, without comprehensively documenting the contexts in which those tags can be used? Or, perhaps you assume some familiarity with XHTML, and expect users to bring their existing knowledge of XHTML, or refer to XHTML documentation, for such information? (In which case, they'd expect to be able to nest p elements inside li elements.)

        1. I applaud your continuing to try to help Atlassian understand, Graham. However, I fear that you and I have exhausted our cred with them. I've already been chided by Scott Farquhar for being "an XML zealot". At this point, it will take a multitude of other voices to help Atlassian understand that our end users (not you and me, but the folks in our respective enterprises whose interests we're trying to proactively represent here) cannot adequately solve RTE bugs and issues with the new advanced editor without much better syntax doc.

          One last try, oh Atlassian Gods: FFS, I'm perfectly capable of taking this rudementary doc up above and  figuring out how to fix your underlying XML code when the RTE fucks up. And fuck up it will, often and surprisingly. For. Ever. Because RTEs always have fucked up, and always will fuck up. For. EVER.

          The problem is not me. I'm a smart cookie. I can reverse engineer your damn undocumented syntax through experimentation as needed. But what about the other nearly 100 heavy users in my 500-user llicense organization? Have they all been working with SGML and XML since 1992? No. Most of them don't know bupkes about XML. So how the FUCK will they be able to use the advanced editor to fix a "broken" page if you don't give them the same basic level of syntax details that you formerly provided for your wiki markup syntax.

          Rant. Fucking. Off. I'm tired of Atlassian's attitude.

           

          1. Anonymous

            Hi Shannon - just wanted to let you know that I fully understand where you are coming from. Reading what you and Graham had to say has been educational and informative in its own right. You both did a great job explaining issues that should be fundamental. It is a shame that Atlassian did not listen or understand the significance of what you said. I could tell even before your quote, that you are being treated by edge-cases; that Atlassian thinks they are going above and beyond by simply listening to two XML-loonies. Well, I think you are representing the opinion of a lot of people who know what they are talking about; the people that recommended systems such as Confluence; the people that support such systems.  You are doing too good a job in fact - what else can be added?

            All the best to you, and thank you for trying.

            Rafael.

             

          2. Thank you, Shannon. I share your frustration.

             

        2. That is, no attributes on any elements, except as shown in this page? I do not see any documentation for the use of the style attribute for indenting and aligning p elements, except as demonstrated in a code listing (generated by the rich text editor) in one of my earlier comments. Or the class="highlight" attribute in tables. Or the class="atl-forced-newline" attribute on br elements.

          Good points, Graham. I've added the alignment style to the documentation as you pointed out. I'll have to look into the other questions for you.

           

  23. Atlassian, in case it occurs to you... please don't answer that "What subset...?" question with something like "Confluence supports all XHTML (body element descendants) ... if you use the HTML macro". Right now, I'm interested in the XHTML markup that can be used in the Confluence storage format without resorting to the HTML macro.

  24. Anonymous

    Regarding this is in my earlier comment:

    When you open the .xml file in your browser, the XSLT would transform/expand the root element into html, head, body, etc., and also transform the various ac:* and ri:* elements so that they stand out clearly among the formatted XHTML.

    I should have been more explicit: by "stand out clearly", what I have in mind is that such an XSLT stylesheet would transform the ac:* and ri:* elements into the same (or very similar) markup as that displayed by the Confluence rich text editor (I've used Firebug: I've seen what that markup looks like). One could go further, and have the XSLT stylesheet transform some of those elements into what you see in the Confluence preview, but I think that emulating the rich text editor display is a more pragmatic goal (more easily attainable with a higher degree of fidelity).

    I can see this "out-of-Confluence editing experience" - a combination of Confluence page source wrapped in some newly coined root element (such as ac:confluence), open simultaneously in your favorite desktop XML editor and a web browser, with the editor using a schema to provide a validating, XML-aware (type ahead/context-sensitive selection lists, etc.) editing experience, and the browser using an XSLT stylesheet to transform the source into an RTE-like view - quite clearly in my mind's eye, and I know how to do it (write the schema and XSLT stylesheet). However: (a) I have a day job, so I have limited time, and (b) it's frustrating - and time-consuming - having to guess, or reverse engineer, many of the details.

  25. Off-topic (sorry), but in case this has happened to anyone else: I've noticed that some of my recent comments have appeared as "Anonymous". I suspect - I could well be wrong - that what's going on here is that I return to this page after a few hours or days away, see that I am, apparently, logged in, add a comment, and then realize that my login must have timed out, because my comment is attributed to "Anonymous". Or maybe I'm doing something else wrong. Either way, in future, I'll try to remember to refresh the page to ensure that I really am still logged in before I add a comment. (Did I hear someone mutter "Stupid newbie?" Yeah, it's a fair cop.)

  26. Here's a rudimentary working example of the XSLT stylesheet I mentioned in earlier comments (for viewing Confluence page source in a web browser as you edit it in your favorite XML editor):

    ConfluenceToXHTML.xsl
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier" xmlns="http://www.w3.org/1999/xhtml">
    
      <!-- Transform Confluence storage format to XHTML -->
    
      <!-- Identity transform: by default, simply copy all attributes and nodes to output -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <!-- Replace the Confluence page root element with XHTML wrapper -->
      <xsl:template match="/*">
        <html xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier">
          <head>
            <title>Confluence page</title>
            <style type="text/css">
            /* <![CDATA[ */
              body {
                font-family: sans-serif;
                background-color: white;
                color: black;
              }
              .markup {
                color: #A9A9A9;
              }
              .element-name {
                color: #800080;
                font-weight: bold;
              }
              .comment {
                color: green;
              }
              .cdata {
                color: #CC0066;
              }
              .text {
                font-family: sans-serif;
                color: black;
              }
              .attribute-name {
                color: #800080;
              }
              .attribute-value {
               color: black;
              }
              div.extension-element {
                margin-top: 0.5em;
                margin-bottom: 0.5em;
                border: 1px solid #DDDDDD;
                background-color: #F0F0F0;
              }
              p.extension-element-markup {
                margin-top: 0.2em;
                margin-bottom: 0.2em;
                padding-left: 0.5em;
                padding-right: 0.5em;
              }
              div.extension-element-contents {
                border-top: 1px solid #DDDDDD;
                padding: 0.5em;
                background-color: #FFFFFF;
              }
              /* ]]> */
              </style>
          </head>
          <body>
            <xsl:apply-templates/>
          </body>
        </html>
      </xsl:template>
    
      <!-- Represent extension elements as their XML source -->
      <xsl:template match="ac:* | ri:*">
        <div class="extension-element">
          <p class="extension-element-markup">
            <span class="element-name">
             <xsl:value-of select="name(.)"/>
            </span>
            <xsl:apply-templates select="@*"/>
          </p>
          <xsl:if test="node()">
            <div class="extension-element-contents">
              <xsl:choose>
                <xsl:when test="name(.) = 'ac:plain-text-body'">
                  <pre><xsl:apply-templates select="node()"/></pre>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:apply-templates select="node()"/>
                </xsl:otherwise>
              </xsl:choose>
            </div>
          </xsl:if>
        </div>
      </xsl:template>
    
      <!-- Represent extension attributes as their XML source -->
      <xsl:template match="ac:*/@* | ri:*/@*">
        <xsl:text> </xsl:text>
        <span class="attribute-name">
          <xsl:value-of select="name(.)"/>
        </span>
        <span class="markup">
          <xsl:text>="</xsl:text>
        </span>
        <span class="attribute-value">
          <xsl:value-of select="."/>
        </span>
        <span class="markup">
          <xsl:text>"</xsl:text>
        </span>
      </xsl:template>
    
    </xsl:stylesheet>

    To use this stylesheet, you need a Confluence .xml source file like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="ConfluenceToXHTML.xsl"?>
    <!DOCTYPE ac:confluence SYSTEM "confluence.dtd" [
      <!ENTITY ndash  "&#8211;">
      <!ENTITY nbsp   "&#160;">
    ]>
    <ac:confluence xmlns:ac="atlassian.confluence" xmlns:ri="resource.identifier" xmlns="http://www.w3.org/1999/xhtml">
    <!-- Copy source from the Confluence Source Editor plugin to here -->
    </ac:confluence>

    where I have further customized the confluence.dtd (which is based, as mentioned in an earlier comment, on the XHTML 1.0 Strict DTD) with the following new lines (to declare the newly coined ac:confluence root element):

    <!ELEMENT ac:confluence %Block;>
    <!ATTLIST ac:confluence
      %attrs;
      xmlns           %URI;      #FIXED 'http://www.w3.org/1999/xhtml'
      xmlns:ac        %URI;      #IMPLIED
      xmlns:ri        %URI;      #IMPLIED
      >

    With this setup, I can edit the .xml file in a validating XML editor (I happen to be using jEdit with XML plugin), and browse the .xml file in Firefox. In Firefox, due to the XSLT stylesheet, the proprietary ac:* and ri:* elements appear in similar (though not identical) fashion to their appearance in the Confluence rich text editor.

    Some issues:

    • Of the three web browsers I've tried (Chrome, IE9, and Firefox), only Firefox works for me. The other browsers appear to restrict local client-side XSLT transformations. I used to use this feature frequently in previous versions of IE; the Googling that I have done seems to indicate that it should still work in IE9 (since the XSLT stylesheet and the .xml file are both local files), so I'm stumped. I'm less familiar with Chrome.
    • This rudimentary XSLT stylesheet uses the browser's default CSS to render most of the XHTML. It would be better if the XSLT stylesheet output link elements that referred to your Confluence CSS files (source editor CSS or preview CSS; not quite the same thing). Maybe in a later version.
    • Ugly: Firefox does not load external DTDs. For the client-side XSLT stylesheet processing to work, you must include in the DTD subset of the .xml file entity declarations for any entity references that you use, such as &nbsp; or &ndash; (hence those <!ENTITY ndash "&#8211;"> etc. declarations in the example listing). Yes, a pain.

    At some point, if I get time (and especially, if anyone expresses interest), I might consolidate the contents of several of my recent comments in a page on some external website, with downloadable files (DTD, XSLT stylesheet, various related scripts). If anyone has followed what I've done so far, it should be fairly easy to reproduce, but I guess it would be easier if I just made the complete, latest files downloadable. But what I'm really hoping is that Atlassian will beat me to it, and render this work obsolete.

    Use of this XSLT stylesheet is not restricted to an xml-stylesheet processing instruction in web browsers. There are many XML applications (XML editors with XSLT capability, as well as standalone XSLT processors) that you could use with this XSLT stylesheet to transform Confluence source into XHTML (essentially, to highlight proprietary Confluence markup, and leave the rest as-is) for viewing in a browser.

  27. Getting back to the schema, I can fully understand why Atlassian was reluctant to introduce a source editor. It's not just a matter of what subset of XHTML elements (and attributes) Confluence supports, but what combinations of XHTML elements - combinations that are valid in XHTML - Confluence supports, and to what extent, and in what context.

    For example, you can use the Source Editor plugin to enter the following source:

    <p>Paragraph above bullet list.</p>
    <ul>
      <li>Bullet 1 of 3</li>
      <li>Bullet 2 of 3
        <p>Paragraph 1 of 3 inside bullet 2</p>
        <p>Paragraph 2 of 3 inside bullet 2</p>
        <p>Paragraph 3 of 3 inside bullet 2</p></li>
      <li>Bullet 3 of 3</li>
    </ul>
    <p>Paragraph below bullet list.</p>

    Back in the rich text editor, you can edit the text of the paragraphs that are nested inside the bullet list items, and those paragraphs will still be there when you save the page. But can you create new nested paragraphs? I can't see how. (I believe the current answer is to use line breaks inside list items.)

    So, one cannot simply say, without qualification, that Confluence supports XHTML <p> and <li> elements (or use the corresponding XHTML schema definitions unchanged). The Confluence rich text editor does not (appear to; I would be happy to be shown otherwise) allow you to create these elements in some of the combinations that are valid according to XHTML.

    Such different degrees of support complicate the task of developing a schema. Sorry for mentioning it again, but such issues would not exist (or at least, there would have been a much better chance of identifying and minimizing such issues) if a schema had been used as a primary reference during design, development, and testing (and was intrinsic to the editor).

    1. But can you create new nested paragraphs? I can't see how. (I believe the current answer is to use line breaks inside list items.)

      I've just managed to do this (create nested paragraphs in a list item in the rich text editor). I would not call it intuitive, but it's possible. So I'll code the DTD I'm working on to allow it.

       

       

  28. This comment describes a request for a new feature (or, if you prefer, a request for a change to the behavior of an existing feature).

    I have deliberately added this request to this page as a comment. I will leave it to you (Atlassian) to decide whether it is worthy of creating a JIRA issue for development.

    Everyone/anyone: please feel free to comment on my suggestions for the names of various items in this request.

    Feature request: Serve page source via WebDAV as an XML document, not an XML snippet (and .xml, not .txt file extension)

    Currently, the Confluence WebDAV plugin serves the source of a page as an XML snippet - that is, a collection of XML elements, without a single root element - in a file with extension .txt.

    Being a snippet prevents the file from being treated as an XML document that can be validated or edited as an XML document in a validating XML editor.

    When serving the page source via WebDAV, could you please wrap the XML snippet in a root element, with a document type declaration, and also (optional, but preferable) an XML declaration, with the file extension .xml (for more convenient association with XML applications)?

    For example, instead of serving the file mypage.txt, like this:

    mypage.txt
    <p>Paragraph text.</p>
    <ul>
    <li>Bullet list item</li>
    <li>Bullet list item</li>
    </ul>

    serve mypage.xml, like this:

    mypage.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE ac:confluence PUBLIC "-//Atlassian//Confluence 4 Page//EN" "http://www.atlassian.com/schema/confluence/4/confluence.dtd">
    <ac:confluence xmlns:ac="http://www.atlassian.com/schema/confluence/4/ac/" xmlns:ri="http://www.atlassian.com/schema/confluence/4/ri/" xmlns="http://www.atlassian.com/schema/confluence/4/">
    <p>Paragraph text.</p>
    <ul>
    <li>Bullet list item</li>
    <li>Bullet list item</li>
    </ul>
    </ac:confluence>

    The example listing above contains my initial suggestions for various items, as described in the remainder of this comment.

    XML declaration

    Suggestion:

    <?xml version="1.0" encoding="UTF-8"?>

    Issues:

    • From the W3C Recommendation for XML: "XML documents SHOULD begin with an XML declaration which specifies the version of XML being used."
    • Are the source files served via WebDAV UTF-8-encoded? I think they are. If not, replace UTF-8 in the XML declaration with the appropriate encoding.

    Document type declaration

    Suggestion:

    <!DOCTYPE ac:confluence PUBLIC "-//Atlassian//Confluence 4 Page//EN" "http://www.atlassian.com/schema/confluence/4/confluence.dtd">

    Issues:

    • The formal public identifier (FPI) is up to you. My suggestion is "-//Atlassian//Confluence 4 Page//EN", but you might want to think about using a more specific version number, or a version number for the schema that is independent of the Confluence product version. And you might not like "Page" (for example, if pages and blog posts will always have the same schema, you might prefer to use a different term that encompasses both; although, I think that "page" is generic enough for this purpose, and one could argue that a blog post is a "specialization" of a page).
    • The system identifier - my suggestion is "http://www.atlassian.com/schema/confluence/4/confluence.dtd" - gives the address (URI) of a DTD for the document, but, in practice, the DTD does not necessarily have to exist at that address (applications might not always have access to network-based resources). In practice, one can use a catalog that maps the FPI to a local copy of the DTD (which is what I have been doing in testing).

    Document root element name

    Suggestion:

    ac:confluence

    Issues:

    • If you plan to have multiple XML vocabularies for Confluence - perhaps blog posts might not have quite the same vocabulary? - then perhaps ac:page might be a better choice of name for this root element (more specific).
    • I have used the namespace prefix ac: (your coinage: I assume, perhaps incorrectly, that this is an abbreviation of "Atlassian Confluence") for the root element. I did this to (a) avoid coining another namespace, and (b) avoid including the root element in the default namespace (that is, elements without a namespace prefix), because you have so far used that namespace for elements and attributes that use the same names as XHTML elements and attributes.

    Namespace declarations

    Suggestions:

    xmlns:ac="http://www.atlassian.com/schema/confluence/4/ac/"
    xmlns:ri="http://www.atlassian.com/schema/confluence/4/ri/"
    xmlns="http://www.atlassian.com/schema/confluence/4/"

    Issues:

    • For the default namespace, I have quite deliberately not used the XHTML namespace name "http://www.w3.org/1999/xhtml". It is apparent that elements and attributes in the Confluence storage format that have the same names as elements and attributes in XHTML do not necessarily share the same characteristics (for example, the contexts in which these elements can appear). To use the XHTML namespace for these elements and attributes would be, at best, misleading.
    • A namespace name must match the format of a URI, but there need not be an actual resource at that URI. I have coined URIs based on my observations of current common practice, but the final decision is, of course, yours. (Note that I have deliberately terminated the URIs with slashes.)
    • I'm least confident about my suggestion for the URI of the default namespace; specifically, the way it ends in just ".../4/" (the Confluence version), compared to the other two namespace URIs, ".../4/ac/" and ".../4/ri/". I could not think of an appropriate choice of term to describe this default namespace. ".../4/xhtml/" felt wrong to me, for reasons already described.
  29. Anonymous

    I'm going to guess that the reason they can't/won't provide a DTD or XSD is closely tied to the reason they deliver WebDAV output as a .txt file and you are seeing no root element or DOCTYPE declaration. And my guess is that they're using XPATH to let their code get at everything they care about in their "implementation details". So essentially, they're approaching XML like non-doc-oriented coders do. Like programmers. They have not approached their XML implementation like doc people do. Just a guess. This is Shannon btw.

  30. I took the liberty of throwing together a very simple plugin that lists all of the macros installed in a given Confluence instance, along with the supported parameters (and the data types of said parameters). The hope is that this will be useful to those who have been wondering about macro parameter documentation. Here's the JAR:

    Arsenale Macro Lister JAR

    To use, install the plugin via the UPM, make sure that you're logged in as an admin, and then browse to YOURCONFLUENCE.COM/admin/macrolister.action

    Caveats:

    • Tested with Confluence 4.2 and 4.1. I'm guessing that it will probably also work with 4.0, but YMMV.
    • This plugin only displays macro parameters that are exposed to the Macro Browser. The output looks pretty comprehensive at first glance, but it's possible that some macros have hidden parameters that are not exposed.
    • No support, no warranty. This was an hour out of my morning and there are no plans to develop it further.
    • The source is available at Bitbucket. Feel free to fork it and do whatever you like.

    If one in the community were so inclined, it probably wouldn't take much more effort to make the plugin output the data in a format that is more amenable to XML-processing applications.

    For example, I can envision a plugin that would automatically output an entire DTD (or at least a DTD-like object, pending resolution of the "no root element" question) that corresponds to all of the entities that are available for a specific Confluence instance, including macros, and presumably integrating the groundwork that Graham has already laid.

    However, I'm not that much of an XML-head, so the latter is a task for somebody else.

    1. Anonymous

      (Shannon here) Thank you, Scott, very much. Now I have a reason to task my IT guys with upgrading our Confluence test server to 4.2 and trying this out.

      Atlassian: If it took an atlassian developer partner only an hour to throw this together, it makes me wonder even more why on earth you guys couldn't be arsed to do something similar when I and others have been asking for this type of info for nearly 4 months now?

    2. Nice one, Scott!

      For my part, I am close to completing a DTD (by trimming and extending the XHTML 1.0 Strict DTD) that does a much better job of constraining the descendants of an ac:confluence element to the markup that the Confluence rich text editor generates than the rudimentary DTD I described earlier.

      By "a much better job", I mean that the DTD will (to the best of my ability, and admittedly with some guesswork regarding variations in possible markup structure, although I am testing it against instances of source generated by the rich text editor) constrain markup to the elements and attributes that the rich text editor generates, including (and here is where the majority of the guesswork lies) the contexts in which the rich text editor can generate those elements and attributes.

      For example:

      • The DTD will only allow an element to have the attributes that are documented on this page as being allowed for that element (plus any other attributes that I happen to stumble across - such as class="highlight" in tables - as I use the rich text editor to generate source).
      • I haven't yet edited the DTD for this specific rule, but I plan to: the DTD will not allow a p element inside an li element, because the rich text editor does not allow it (to my knowledge, as I've mentioned on this page, so far without confirmation from Atlassian).

      The DTD will not constrain the specific values of attributes, except in a very few cases (such as the ac:name attribute of the ac:emoticon element). For example, the only attribute that the DTD will allow on a span element is style, but the DTD will not constrain the specific values of the style attribute. So the DTD will allow attribute values that the editor will not generate, and therefore - based on advice on this page from Atlassian - might, potentially, remove.

      Regarding Scott's work: the DTD will not constrain the descendants of an ac:macro element based on the value of its ac:name attribute. I do not know whether a DTD can express such constraints (I need to do some more reading). I am more familiar with the W3C XML Schema 1.0 language, which I know cannot. Other schema languages, however, such as Schematron, can.

      By "close to completing", I mean in the next few days, or maybe as long as a week, depending on how much time I can steal from other tasks. Experimenting with the rich text editor and guessing possible variations (to save yet more experimentation) is time-consuming. The documentation on this page provided by Atlassian is a useful reference, but (as per earlier comments on this page) is far from sufficient to develop a DTD. For this exercise, I am treating the rich text editor (or rather, source generated using the rich text editor) as the definitive reference for the storage format. Currently, I see no other option.

      When I've completed this DTD (to the best of my ability: I have no insight into the Confluence storage format other than the documentation on this page and the source I generate using the rich text editor), I plan to turn my attention to generating the corresponding XSD (or rather, suite of related .xsd files; one per namespace used by the Confluence storage format). Again, I hope Atlassian beats me to it.

      1. Regarding this statement in my previous comment:

        the DTD will not allow a p element inside an li element, because the rich text editor does not allow it (to my knowledge, as I've mentioned on this page, so far without confirmation from Atlassian).

        I was wrong; the rich text editor does allow it (I've just done it), so I'll code the DTD to allow it, after all.

    3. The details returned by the methods of the MacroParameter class look very promising. For example: isRequired(), getDefaultValue(), getDescription().

      Also the methods of the MacroFormDetails class: getNotationHelp(), getDocumentationUrl(), isFreeform(). I haven't had time to investigate any further, but the description of the isFreeForm() method - "true if the macro parameter information is not available" - sounds suspiciously - to my cynical mind  (wink) - like a potential "get out" clause for plugin developers who have not taken the trouble to document their plugins in a manner accessible via these methods. However, note that this is just a suspicion, born of a mix of my own ignorance and cynicism, not an assertion, and I want it to be wrong.

      Completely setting aside for now the idea I described in another comment for encoding this information in an XSD, it looks like it would straightforward (as Scott himself says) to enhance/extend Scott's plugin to output fairly (note the deliberately vague qualifier (smile) - I'd need to try what I'm about to describe) comprehensive XHTML-source (or Confluence storage format-source) documentation for macros. I'm not about to do this right now, however, because that would be a distraction from refining the DTD/XSDs. But it looks doable to me.

       

  31. Some errata (omissions in the documentation in this page), based on my latest experimentation in the source editor and validation of the source in a Confluence 4 "sandbox":

    • The ac:name attribute of the ac:emoticon element can also have various other values not listed in this page (such as question and minus, among others; this is obvious if you look at all of the available options in the rich text editor)
    • The a element can have class and rel attributes. For example:

      <a class="external-link" href="http://localhost:9999/help/index.jsp" rel="nofollow">

    • The ul element can have a class attribute. For example:

      <ul class="alternate">

    I cannot reproduce the last two items (for the a and ul elements) using the Confluence 4 rich text editor, so perhaps these attributes are artefacts of the Confluence 3-to-4 conversion (the pages in which these attributes occur were created in Confluence 3.x). Either way, I'm going to allow these attributes on these elements in the DTD, so I might need to expand my definition of what I'm covering in the DTD to include not just what can be created in the Confluence 4 rich text editor, but also what can exist in source converted from Confluence 3. Atlassian, any comment on this? (When I open these pages in the Confluence 4 rich text editor, save the page, and then edit again and inspect the source, these attributes remain.)

     

     

  32. A draft DTD for the Confluence storage format

    I have made available for download a draft DTD for the Confluence storage format in a .zip file that also includes three .ent files referred to by the DTD (as used by the XHTML 1.0 Strict DTD).

    This is an ad hoc, temporary location for these files; not intended to be a permanent home. I hope that Atlassian will soon render these files obsolete by providing a definitive schema (here, I'm using "schema" in the generic sense that encompasses both DTDs and W3C XML Schema - XSD - documents).

    To use this DTD, extract the contents of the .zip file to a folder where you have a .xml file containing Confluence page source in the following "wrapper":

    <!DOCTYPE ac:confluence SYSTEM "confluence.dtd">
    <ac:confluence xmlns:ac="http://www.atlassian.com/schema/confluence/4/ac/" xmlns:ri="http://www.atlassian.com/schema/confluence/4/ri/" xmlns="http://www.atlassian.com/schema/confluence/4/">
    <!-- Copy source (for example, from the Source Editor plugin) here -->
    </ac:confluence>

    then open the .xml file in a validating XML editor (for example, Altova XMLSpy).

    In case it needs to be said: this DTD is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.

    Regarding the .ent files in the .zip: I do not know whether the Confluence storage format supports all XHTML character entities (such as &nbsp; ). I know that the Confluence rich text editor "Insert Symbol" option does not display all of the symbols available in XHTML. For now, this DTD uses the XHTML .ent files as is.

    I have had to make guesses about some markup structures. It would not surprise me to find out that some of those guesses were wrong.

    This DTD allows/describes (to the best of my ability and understanding) markup consisting of the superset of the following intersecting sets:

    • Markup that the Confluence 4 rich text editor can generate (more specifically, the markup that I have been able to make the rich text editor generate)
    • Markup described in the documentation in this page
    • Markup in the page source of my local "sandbox" installation of Confluence 4 (where most of that page source has been migrated from Confluence 3.x, and has not yet been edited in Confluence 4)

    This DTD is a stepping-stone to an XSD, which can then be annotated and transformed into XHTML-source documentation for the Confluence storage format.

    It's a start.

    Feedback welcome.

  33. Atlassian, so far you have not responded to my request (made in an earlier comment) for a .zip of a set of Confluence XML page source (from your public pages). That would have made the job of developing the DTD to this stage easier, and would have improved my confidence in its fidelity. (As I've mentioned, my "test bucket" of page source consists of a relatively small set migrated from Confluence 3.x, mostly not yet updated in Confluence 4, and brand new pages that I have created in Confluence 4 specifically to "exercise" the full set of markup that the Confluence 4 rich text editor can generate.)

    I see no (public) progress on CONF-24884 - Getting issue details... STATUS .

    Could you please either (preferably, both):

    • Send me (or otherwise make available for download) a nice fat .zip of Confluence 4 page source that I can use to confirm and/or correct the guesses that I have so far had to make (regarding, for example, the child elements that each element can contain).
    • Download the DTD that I have developed, use it yourself, and send me your feedback.

     

  34. While developing the DTD, I noticed that, of the elements in the Confluence storage format that have the same name as XHTML elements, all except two exist in XHTML 1.0 Strict. The elements s (strikethrough) and u (underline) are "interlopers" from XHTML 1.0 Transitional. I make this comment to forestall anyone claiming that elements in the Confluence storage format that have the same name as XHTML elements are all from XHTML 1.0 Strict. (Who would do that? Er, perhaps the same people who said that the Confluence storage format is XHTML? (wink) )

     

  35. Some source I've just generated using the rich text editor:

    <ol>
      <li style="list-style-type: none;">
        <ol>
          <li>Numbered list item (indented once)</li>
        </ol>
      </li>
    </ol>
    <h5 style="text-align: center;">Heading 5 (align center)</h5>
    <h4 style="margin-left: 30.0px;">Heading 4 (indented)</h4>

    So, li and heading elements can have style attributes, which is not shown in the documentation in this page. (In case someone reads this and goes "Duh! Of course they can!": I know this is possible in XHTML, but I'm talking about the Confluence storage format; and, in particular, what markup the Confluence rich text editor can generate.)

    In case you're wondering, I created that li with style="list-style-type: none;" using the indent toolbar button.

    Following on from my previous questions on this subject: I don't know if you (Atlassian) plan to add this level of detail (which attributes are allowed on each element) to the comprehensive (sic) documentation on this page, but I'll be adding this discovery to the DTD.

    You haven't yet answered my specific questions regarding exactly what you mean by "comprehensive". I've already noted that it does not include complete information about which elements can be contained inside other elements, but I've so far assumed that it does include which attributes can be used on each element (except for inadvertent omissions, which you've added as I've pointed them out), so I've been pressing ahead with the DTD on that basis. However, it seems now that the documentation in this page includes only some examples of which elements can have particular attributes (such as style); this incompleteness might be inadvertent, I don't know.

    1. Summary of some thread posts further up, in chronological order:

      1. Bill Arconati removes all the "TBD" checklists at the top of this page, which effectively means "hey! we're done with this doc!"
      2. I post a comment saying all manner of important details are missing and they can't possibly think they're actually "done".
      3. Bill posts a vague reply: "We haven't finalised the doc - The intention was to remove the completed items and provide more helpful information to users like who can view and edit the source and how they do it."
      4. I ask: "Then why did you remove the table?"
      5. Bill gives no answer.
      6. I email the CEOs and ask: "What gives?" and explain yet again why the syntax details are important and gee maybe you want to look into this thread.
      7. Scott Farquhar replies to me via email that (essentially) "I cannot promise you that we will document the details you are asking for, and furthermore you haven't convinced me that such details are necessary, and oh by the way 'unfortunately you come across as an XML zealot because I can't figure out what your specific use-case is that you're trying to solve' and 'I wonder if all the effort you've expended trying to convince us would have been better spent solving the smaller, more specific problem that you must be having (but I still don't understand).' " Ya, he actually said that stuff to me that I highlighted in italics. Those are non-edited straight quotes from the mouth of an Atlassian CEO. Honestly, does anyone else here in the user community have trouble understanding my explanations why non-existent syntax details for the atlassian core macros might be a problem for us?
      8. Bill later answers one of your questions with his statement that "the documentation on this page is comprehensive" (which contradicts what he said in point #3.
      9. You ask for detail and also point out that you're finding all manner of conflicts with the apparent "comprehensiveness" of the above doc.
      10. So far: crickets in response to point #9.

       

      Hey Scott, you know that "use-case I'm trying to solve that you can't figure out" Here ya go (yet again):

      Use Case: When your RTE breaks a page, and a user needs to go fix the broken stuff in the advanced editor, they need to know what the legal syntax is. They need to know what elements can be put inside which other elements, and they need to know the attributes that are allowed on elements. They especially need to know the attributes that can be set on your ac: and ri: elements that comprise all your core atlassian macros that come with Confluence. Otherwise, how can they understand how to fix the broken page? BTW, us 'XML zealots' use the term Content Model to refer to this collective set of information about what elements can be put inside other elements, and the specific ordering and combination of such, and the attributes that can be used in each element. It's kind of a standard aspect of XML documentation that everyone who needs to work with XML expects. And your advanced editor requires us to work with XML that is proprietary to Atlassian and documented nowhere else, so we are reliant on YOU to provide that information.


      And just in case you are surprised by a use case that centers around "When your RTE breaks a page" Here's yet another example, from just today (posted by another user in the 4.0 Feedback thread), of just how badly your RTE can fubar a page. This has been the case for 7 months now and will be the case forever.

      New Editor Lost my Formatting

      I had a really annoying bug today. I had a page with a bunch of different headings, and a no-format macro that had existed for some time. I edited the page to insert a new paragraph with a new heading. Part of the content was numbered lists, and there was some cutting & pasting involved and much faffing to get the lists looking right. I definitely only entered text within the dozen or so lines I was editing.

      When I saved the page, the heading formatting had been removed from all the headings after where I added my text. One of those headings also had a numbered list, and this formatting had been removed too, inserting blank lines. And finally, I had a load of text in a no-format macro - the macro was removed, leaving all my text all over the place.

      To fix the formatting I had to spend time changing it all back again (could not revert, otherwise would have lost my new content). The macro was a pain, as it concatenated all my unformatted text into a single line, so I had to go through very carefully to put it back again after reinserting the macro.

      I have not tried to repeat, as frankly I wasted enough time fixing the after effects.

      1. Shannon,

        If you're going to quote things from a private email, how about I just post my entire reply:

        Shannon,

        As I mentioned in previous emails - I still don't understand your use-case.  You mention we need to document lots of things, but I still don't know what you're unable to achieve.
        Do you have a script you have that each night creates content?  Or something else?  I've read, and re-read your comments, and unfortunately you come across as an XML zealot because I can't work out what your specific use-case is that you're trying to solve for.  You've never asked "I need the syntax for macro X because I'm struggling to create a page programatically".  
        I wonder if all the effort you've expended trying to convince us would have been better spent solving the smaller, more specific problem that you must be having (but I still don't understand).
        If what you're saying is "unless you document every element in your new editor right now, then we'll have to migrate off our Confluence instance", then whilst I'm extremely sad to see you go, I'm afraid that I don't believe we'll make you happy, and I don't want to promise that we will.

        I really appreciate your passion for us, and our products, and it upsets me that we can't meet your bar.  Have a good Easter (if that is indeed a holiday wherever you are).
        Cheers,
        Scott
        Your comment above about a "end user fixing our syntax in the advanced editor" is way better than anything I've heard before as to why you are so passionate about this.  However, I still think we're prioritising right:
        • We're focused intently on improving the editor and removing any bugs that are reported
        • End users aren't going to be wanting to fix XML
        • Even if they did - doubtful they're going to be looking up elements in a DTD to see if they've got them correct
        • Whilst I haven't looked through comprehensively, I haven't seen any bugs that affect the attributes on the core macros we ship with Confluence.  So documenting these won't help your use-case?

        But this seems at odds with what you're passionate about, so I do worry I've missed something that you must be seeing?

        Scott

        1. Hi Scott,

          Thank you for the information on Atlassian's priorities and focus. This makes it clear to me - please correct me if I've misunderstood you - that Atlassian does not see developing a DTD/schema for the Confluence storage format as a high priority. (Lack of activity on  CONF-24884 - Getting issue details... STATUS was a clue (wink) .)

          This makes me feel better about developing a DTD myself, because - again, please correct me if I'm wrong - it seems unlikely that Atlassian will be spending any time on this soon. And I am not going to spend any more time trying to convince you otherwise. I understand that, If I want a DTD/schema now, that's my issue.

          I would still appreciate it, though, if you would make available to me a .zip of Confluence page source files from your public pages, as I've requested in previous comments. That should only cost you a few minutes, and it would help me to test and refine the DTD.

          1. Hallo Graham (smile)

            Following up on your request: "I would still appreciate it, though, if you would make available to me a .zip of Confluence page source files from your public pages".

            We make XML exports available for the documentation of all our products. These exports are produced via the standard Confluence space export to XML. (The XML is a proprietary format, used to recreate the Confluence space by importing the XML into another Confluence site.) The XML file includes elements that contain the XHTML-based storage format in CDATA-defined sections, comprising the content of the pages.

            The XML exports for the various product documentation sets (Confluence, JIRA, GreenHopper, etc) are linked from the child pages of this page: Atlassian Documentation. The child pages are called "X Documentation Directory", where "X" is the product name. So, for example:

            • The link to the Confluence XML export is on this page: Confluence Documentation Directory, under the heading "Latest Versions of Downloadable Documentation". This one is very large, as the Confluence doc space is large. Here's a direct link to the latest XML export. (That's for Confluence 4.1. The Confluence 4.2 export is coming soon.)
            • The link to the JIRA XML export is on this page: JIRA Documentation Directory. I'd recommend this one, as it's a reasonable size.  Here's a direct link to the latest XML export
               

            To find the page content:

            1. Unzip the zip file.
            2. Open the file named entities.xml.
            3. Search for property name="body"
            One more tip: Our older doc exports are from earlier versions of Confluence, and therefore contain wiki markup instead of the XHTML-based storage format.
            I hope this is useful information!
            Cheers, Sarah

             

            1. Hi Sarah,

              Thank you very much! Yes, very useful information.

              Especially this (I had no idea!):

              We make XML exports available for the documentation of all our products.

              I've downloaded "Confluence 4.1 Complete Documentation (XML) DOC-20120110.zip" and found the page content as you described. Thank you very much for the direct link and the detailed tips.

              Here's what I'm going to do:

              1. Write a script that extracts the contents of each <property name="body"> CDATA section (that is, the XML snippets of Confluence storage format - that the Confluence WebDAV plugin serves in .txt files, and that are displayed in the Confluence Source Editor plugin), wraps it in a root element (as described in my earlier comments), and then saves it to an .xml file.
              2. Attempt to validate those .xml files against the DTD and XSDs that I have developed.

              I'll iteratively tweak the DTD/XSDs to cater for any markup that I haven't seen before, and I'll let you know (in comments on this page) about markup I find that isn't yet documented in the body of this page.

              I'll also point out any "odd" markup (I'm deliberately avoiding the term "invalid" here) that I see, such as the ul element without li children that I reported observing in source in my local Confluence installation.

              Thanks again! (smile)

              P.S. I don't mean to poke you with a stick - I'm sincerely grateful for your help - but I could not suppress a rueful smile when I saw those XML snippets - the page source - wrapped in CDATA sections in entities.xml, so that they are treated as text data, not parsed as XML. Actually, I would have been a little surprised if they hadn't been wrapped in CDATA sections, because those CDATA wrappers are consistent with Atlassian's approach in related areas, such as the way the WebDAV plugin serves (root-less) XML snippets in .txt files.

            2. Hi Sarah,

              I've "exploded" the page body content inside entities.xml into one .xml file per page, and I'm now validating those .xml files.

              An issue that I've hit immediately: many of the CDATA sections nested inside the page contents - for example, inside ac:plain-text-body elements - are unterminated, causing XML parsing errors (for example, "CDATA section not finished ... Premature end of data in tag plain-text-body").

              Specifically, rather than ending with the required string "]]>" (without any whitespace between those characters), the content contains the string "]] >" (two right square brackets, then a space, then a right angle bracket). I have confirmed that this is an issue in the original entities.xml file (rather than an issue introduced by my processing).

              Any document containing this error cannot be validated, because it is not well-formed XML. Could you please pass this observation on to the Confluence developers? I think it deserves its own JIRA issue. Atlassian has made it clear that validation of Confluence page source against a schema/DTD is not high on its list of priorities, but it might, perhaps, be interested in at least generating well-formed XML.

              I found 17192 occurrences of "]] >" (the string with the problematic space) in entities.xml.

              For now, as a temporary workaround, I'll do a search'n'replace to get past this error, so that I can proceed with validation.

              In counting the instances of this error, I also stumbled across the following "monster" (BodyContent id="167933": numerous CDATA-related issues here, including nesting of CDATA sections, which is not allowed):

              <ac:macro ac:name="noformat"><ac:plain-text-body><![CDATA[
              <property name="name"><![CDATA[Test Space]] ]] ><![CDATA[></property>
              <property name="key"><![CDATA[test]] ]] ><![CDATA[></property>
              ]] ></ac:plain-text-body></ac:macro>

              (I'll just have to pass over any such things for now, rather than attempting to fix all of the CDATA issues by hand.)

              There is some good news: not all of the documents have this problem. Some do validate.

              1. Hi Sarah,

                With apologies, I take back everything I wrote in my previous comment (about malformed CDATA section terminators). The ride home from work cleared my head. I suspect that the Confluence developers deliberately inserted those spaces to avoid nesting CDATA sections in entities.xml, because the <property name="body"> element already introduces a CDATA section. On import, I suspect that Confluence strips those spaces (just like I'm about to do).

                D'oh! (wink)

                 

                1. Just clearing my conscience of this issue (because I'm not going to investigate it any further myself right now). Even after replacing the string "]] >" with "]]>", the following BodyPage IDs in that entities.xml have unfinished CDATA sections:

                  • 200674951
                  • 256183376
                  • 256183433
                  • 258508054
                  • 258509164
                  • 260800740
                  • 260800885
                  • 260804655
                  • 264078755
                  • 264078756
                  • 264078771
                  • 264732873
                  • 264738228
                  • 265453753
                  • 265866776
                  • 266666912
                  • 270010910

                   Perhaps this is because they have some variant of "]]>" with embedded whitespace that I haven't checked for, or perhaps it's some other issue, I don't know, but I thought I'd at least report it. Moving on!

                   

                   

                2. You shouldn't apologize, Graham, this is a deep, deep flaw in their format, and reveals a fundamental misunderstanding of how to use XML.  The CDATA / Nesting section on Wikipedia describes a much better work-around for the problem of not being able to nest CDATA sections – just split them somewhere inside the "]]>".  

                  CDATA sections are just a different way of escaping text, and were provided as syntactic sugar so that text areas that are rich in "<", ">", "&" and the like don't have to be entered as a mess of character-entities ("&lt;", etc.).  But what the Atlassian folks have done, rather than to tweak their serializer, is, as you indicated in your original comment, to corrupt the content so that it no longer validates.

                  Sigh.

            3. Atlassian,

              This comment describes issues (such as markup not documented in the body of this page) found in page source in the entities.xml file in the Confluence export "Confluence 4.1 Complete Documentation (XML) DOC-20120110.zip". "BodyPage ID" values in this comment refer to the value of the <id name="id"> element of the relevant <property name="body"> element (that contains the page source in question), in case you want to look up the cited source examples in the entities.xml file.

              For each issue, could you please let me know (although I realize it's entirely up to you whether you respond at all to this comment) whether it represents (a) an error/glitch in the source; (b) markup that can be reproduced using the rich text editor (it would be helpful if you could describe how); (c) markup that is an artefact of migration from Confluence 3 and is tolerated by, but cannot be reproduced by, the rich text editor; (d) markup that can only be introduced via the Source Editor plugin, but is tolerated by the rich text editor; or (e) something else.

              With apologies for the poor formatting... I'm in a hurry tonight...

              I have found class attributes on the following elements (class attribute not currently documented in this page for these elements): p, span, tr, code, table, br

              e.g. <tr class="confluenceTr"> in BodyContent ID 264078105

              and also (I think I might have mentioned this earlier):

              <br class="atl-forced-newline" />

              I have found style attributes on the following elements: table, tbody, tr, th, strong (empty value!)

              e.g. <strong style="">Content Orientation</strong> in BodyContent ID 163447725

              In BodyContent ID 269225191:

                    <table style="margin-left: 1.0px;">
                      <tbody style="text-decoration: none;margin-left: 0.0px;">
                        <tr style="text-decoration: none;margin-left: 0.0px;">

              Undocumented ac:tooltip attribute of ac:link element (BodyContent ID 270014480):

              <ac:link ac:tooltip="learn-more.png">

              ol elements in structure that would not be valid in XHTML (BodyContent ID 139250):

                <ol>
                  <ol>
                    <li>
                      <ac:macro ac:name="include">
                        <ac:default-parameter>Navigating to the Space Permissions View</ac:default-parameter>
                      </ac:macro>
                    </li>
                    <li>Click the '<strong>Edit Permissions</strong>' button.</li>The '</ol>
                </ol>
                <ol>Edit Space Permissions' screen appears, as shown below.</ol>

              div element in 160039091 (can't reproduce in rich text editor - 49 occurrences in 49 files):

                <h3>Confluence 4.1</h3>
                <div>
                  <ul>
                    <li>Autoconvert for Pasted Links</li>
                    <li>Image effects</li>
                    <li>Quick find and replace</li>
                    <li>Follow Your Network On the Dashboard</li>
                    <li>Space attachments macro</li>
                    <li>Global PDF stylesheets</li>
                    <li>Use any character in page titles</li>
                    <li>New translation feature</li>
                    <li>More in the <ac:link><ri:page ri:content-title="Confluence 4.1 Release Notes" />
                        <ac:plain-text-link-body><![CDATA[release notes]]></ac:plain-text-link-body>
                      </ac:link>
                    </li>
                  </ul>

              div element in 263454906:

                <p>
                  <span style="color: rgb(0,0,0);">
                    <span style="color: rgb(0,0,0);">
                      <span style="color: rgb(0,0,0);">
                        <br />
                      </span>
                    </span>
                  </span>
                </p>
                <p>&nbsp;</p>
                <div>&nbsp;</div>
                <div>&nbsp;</div>

                </div>

              Undocumented cite element in 261785286:

                      <td>
                        <p>
                          <cite>citation</cite>
                        </p>
                      </td>

              tr element without children (10 occurrences: wouldn't be valid in XHTML 1.0 Strict). For example, in 264738120:

                    <tr></tr>

              br as block-level element (again, wouldn't be valid in XHTML 1.0 Strict):

              <br class="atl-forced-newline" />
              <br class="atl-forced-newline" />
              <br class="atl-forced-newline" />
              <br class="atl-forced-newline" />
              <br class="atl-forced-newline" /><p />

              Looking forward to hearing back from you on these issues. I'd rather get confirmation from you about their status (glitch or supported; if supported, how and to what extent) before updating my DTD/XSDs to allow the markup as valid.

              1. I can answer some of these:

                'cite' element: This is an example for a wiki markup text effect, documented at Confluence Wiki Markup. It cannot be entered directly by the new editor, but you can use the wiki markup dialog to insert it, e.g.:

                ??This is a citation??

                ac:tooltip attribute: This is a feature that was available in wiki markup, but is no longer supported in the new editor. It can still be entered using either the Advanced tab on the Link dialog or with the autoconvert feature in the editor, e.g. type:

                [linktext|Home|This is a tooltip]

                 

                 

                1. Thanks, Mark. Then, unless you recommend otherwise, I will update the DTD/XSDs to allow the cite element and the ac:tooltip attribute.

                  Do you (Atlassian) plan to add these to the documentation in this page?

                  Two down, quite a few more to go (wink)... I'm looking forward to Atlassian's response to the rest of those markup issues.

                   

                2. Atlassian,

                  Is there any other Confluence source format markup - such as the cite element - that is not documented in this page, and that cannot be entered directly using the rich text editor, but can be inserted via the wiki markup dialog? (I'm still waiting for clarification of what you mean by "comprehensive"!)

                   

              2. The atl-forced-newline guys can only be created either via migration of wiki-markup or by using the 'insert wiki' dialog.

                They are the result of migrating a double-backslash wiki string. This was introduced into Confluence about 3 years ago when we fixed a bug where such strings used to be rendered as <br clear="all">. This could cause a lot of trouble (e.g.  CONF-10850 - Getting issue details... STATUS  or  CONF-11172 - Getting issue details... STATUS ) and so the class was used instead to allow any cases where we did actually want 'clear=all' behaviour to still be retained via CSS.

                Basically, they are there for compatibility.

                1. Cool, thanks. I've just checked: looks like I've already allowed the class attribute on the br element in the DTD/XSDs.

                  Minor point: do you think I should constrain the value of the br class attribute to "atl-forced-newline", or (as I do now) allow any value?

                   

                  1. Well the schema or definition is going to be of use in the creation of new content. So I would say it is preferable not to allow any classes on br. The fact you have to allow 'atl-forced-newline' is unfortunate legacy.

                    In an ideal world you would be creating as clean a definition as possible for the creation of new content, with an extension to that allowing validation of "legacy" content...if you were looking for more work to do (smile)

                     

                2. Paul, I forgot to ask for confirmation: in the Confluence storage format DTD/XSDs I'm developing, should I allow br as a block-level element, as per that example I showed from Atlassian's own source? (For example, as a child element of the document root ac:confluence - my coinage - element? This wouldn't be allowed in XHTML.)

                  Something to consider (with apologies if this amounts to teaching you how to suck eggs): by allowing such things (elements with the same name as XHTML elements, but used in contexts not allowed by XHTML), are you compromising Confluence's ability to export/render/present (valid) XHTML? Or does Confluence shuffle the position of such br elements to make the markup valid? (I'd be surprised.) Or perhaps exporting/rendering/presenting valid XHTML is not a goal of Confluence? ("Schemas? We don't need no stinking schemas! Soup's up!" (wink) )

                   

                  1. Again, it comes down to two different 'use-cases'.

                    For newly created content we strive not to deviate from XHTML. So <br> should not be allowed as a block level element. In addition, should you edit 'legacy' content that has these <br> elements at block level the new editor should clean them up making the content valid.

                    However, until all migrated content has been touched by the editor you will need to expect that you can encounter the rogue <br>'s you are seeing at block level.

                    In the future (probably far-future) once wiki-markup is completely removed from Confluence we would hope to be at a position where the validity of our storage format is guaranteed. However where we are at the moment means we still use or see the effects of the wiki renderer which was designed to output HTML 4, and even then not always correctly. During the Confluence 4.0 development cycle we done what we could to cleanup this wiki renderer output but there are still corners such as those you are finding.

                    And as you say, our primary goal is not to export/render/present valid XHTML. However, our goal is not to export/render/present tag soup either. Dealing in XHTML is in there amongst all the other (thousands of) requirements, but it is definitely not at the top of the list. Which I don't need to tell you! (smile)

                     

                    1. Thanks very much for the detail, it's much appreciated.

                      From your earlier comment:

                      Well the schema or definition is going to be of use in the creation of new content. So I would say it is preferable not to allow any classes on br. The fact you have to allow 'atl-forced-newline' is unfortunate legacy.

                      The use cases that I have in mind for the DTD/XSDs include validating Confluence 4 source immediately following migration from the Confluence 3.x format, to check that the migration has produced valid Confluence 4 source before proceeding.

                      I imagine that you (Atlassian) must already have code to check that the 3-to-4 source migration was successful, even if that code is not included in Confluence distributions, and was only used internally, to test the process during development. I realize I'm sounding like a broken record, but I would have used a schema for that. And probably not just DTD/XSDs, either; I'd likely also have used Schematron (note: I have never used Schematron, but I feel the opportunity coming on (wink) ) or some other schema language that can express tighter constraints than DTD/XSDs. I understand that you could write your own bespoke code to do everything that validation using these existing schema languages does, but that would be a lot of work, and it would be reinventing the wheel.

                      The idea that it might be acceptable (or "working as designed") for migrated content to be invalid (for example, those rogue <br>'s) until it has been touched by the editor is a new one to me, and frankly, I'm struggling with it, because I immediately think, "Uh oh, that means two schemas (if you prefer: two XML vocabularies, similar but different): one (that might contain, for example, markup structures that would not be valid in XHTML) for post-migrated-but-not-yet-touched-by-the-editor, and another for touched-or-created-from-scratch-by-the-editor, with different constraints".

                      I would have thought that it would have been preferable for the 3-to-4 source migration to produce Confluence 4 source that is valid, and so does not need to be touched by the editor to be valid (one schema to rule them all). However, as Zach Miller wrote elsewhere, it is what it is. I am grateful for and sincerely appreciate your openness and the level of detail that you have offered, and I am not about to flame you for it.

                      So <br> should not be allowed as a block level element.

                      Done (DTD/XSDs left, in this case, as per the XHTML rules).

                      A repercussion of this is that attempting to validate source that has not yet been touched by the editor (er, "virgin" source? (wink) ) will result in errors for these rogue <br>'s. I'll try to remember to document that, either in the DTD/XSDs, or in the readme for the package. (I'm not about to try to develop or maintain a separate - "virgin" - variant of the Confluence 4 DTD/XSDs purely for post-migration checking.)

        2.  However, I still think we're prioritising right:
          • We're focused intently on improving the editor and removing any bugs that are reported
          • End users aren't going to be wanting to fix XML

          I think this is a false assumption. Yes, it's true they'd rather fix wiki markup syntax because it's easier to learn and understand and human-read than XML. But users won't think of it as "fixing the XML". They'll think of it as "fixing the syntax that the RTE broke". Ultimately, users of any web-based RTE think of two modes: RTE mode and syntax mode. Every other web-based RTE has a "view HTML" button and users who can't get the RTE to do what they want are often quite happy to go in and muck with the HTML to get the rendered results they want. Well, perhaps not happy, but willing(smile)

          • Even if they did - doubtful they're going to be looking up elements in a DTD to see if they've got them correct

          Yes, you are absolutely correct: they will not want to look up elements in a DTD (or XSD). However, they will expect to be able to look up the legal/possible syntax in a more documentation-style language reference. You know, like your old wiki syntax reference in the notation guide.

          This is my entire "sticking point": you seem to think I'm asking for a DTD or XSD. You are conflating my requests with Graham Hannigton's request, perhaps? I'm not asking for a DTD/XSD although I can see the value in providing that too. My primary concern is supporting my 100 active users with the information they will need to fix their pages when your 4.x RTE does something unexpected. I cannot have those 100 users coming to me to fix their problems for them. They need to be able to see the syntax rules for themselves and acting accordingly. You have a good start up above, but it's woefully incomplete in that it does not describe all legal attributes for all of your core Atlassian macros. Nor does it even accurately describe all the legal and "not legal" (aka won't render properly) content models (remember, this includes attributes rules too, not just element nesting rules) for your elements that you've borrowed from XHTML.

          I've harped on your lack of a DTD/XSD in this regard merely to point out that if you folks had actually based your architecture on a true DTD/XSD, we would not be having this conversation because it would be a trivial task for one of your tech writers to effectively translate that DTD into a proper language reference. In roughly 8 heads-down hours or less. I know because I've done exactly this myself several times in the past. And your DTD ain't really all that complex or deep, honestly. If you'd "done XML right" (yes, I know that's a debatable point, okay sue me (smile)), one of your tech writers long ago would have said internally "just give me the DTD and I'll whip something up and make them happy." Alternatively, one of us in the user community would have said: "just give me your DTD/XSD and I will write a freaking language reference for my users and give it to you to use as well."  Oh wait, I seem to remember Graham saying exactly this twice already. And even pointing you guys to a 3rd party resource that could easily do it for you and not require you to commit even a measly 8 hours to one of your own tech writers.

          • Whilst I haven't looked through comprehensively, I haven't seen any bugs that affect the attributes on the core macros we ship with Confluence.  So documenting these won't help your use-case?

          Bad assumption again. Your core macros get broken quite often in cut/copy/paste/drag-move operations that span across (or encompass) multiple macro content boxes. When that happens, and a user goes into the advanced editor to do the surgery needed to fix the page, they will want to know how to cobble the broken macro back together again in the XML syntax. What I've seen happen myself (and others have reported here) is an entire macro element gone missing after a cut/copy/paste/drag-move. I don't want to be flipping back and forth between RTE and XML mode when fixing the damage. I want to stay in XML mode and be sure of my syntax. How can I recreate a {toc} or {children} macro that got eaten if you don't document the syntax for me? Besides, there's another angle here too, which is that some things are still easier to do in syntax mode:

          • Your text entry boxes in the RTE for defining macro parameters are often woefully too small. Our tech writers commonly use include or exclude strings for {toc} macros that are 3x or 4x or 6x longer than is visible in the RTE editor for those attributes. It's much easier to scan these for problems or edit them in syntax mode where we can see the entire string at a glance.
          • It's common to need to search for specific macro attributes, and being able to look at a syntax reference page for the "code" portion of what we're searching for is 3x faster/easier than opening a new tab, creating a dummy page, then entering a dummy macro in RTE mode to enter the attributes we're searching for, then flipping that page to syntax mode to view the syntax we should use in our search. Don't shake your head: stuff like this is done a lot by the majority of your heavy Confluence users.

          But this seems at odds with what you're passionate about, so I do worry I've missed something that you must be seeing?

          Yes, you have. (smile) Hopefully the foregoing helps in that regard.

        3. I can't speak for Shannon but the compelling use-case I'm seeing develop here is this:

          • Edit confluence content via WebDAV using a client-side standalone XML editor. 
            • If our devs could edit wiki pages in Eclipse they would be in heaven. Yes, they already can do it via WebDav as text files but the experience would be so much safer if validation were included.
          • Ensure that said client-side editor doesn't break Confluence by limiting its output to what Confluence considers valid. 
          • For bonus points: Enable the ability to preview XML editor content via an XSLT transform to renderable XHTML.
            • I massively prefer the idea of editing a plain text format and seeing immediate side-by-side feedback about how it'll render than trying to edit the rendered version in an RTE.

          Your XML format is This Close >< to enabling that approach which would make life SO MUCH better for advanced users.

          I'm surprised you think "End users aren't going to be wanting to fix XML". Although you've grown to be so much more, your core competency as a company is building tools that enable agile development in software shops. Consequently, I would think that many of your "end users" are developers and sysadmins. That's what our company is. I sold the Confluence 4 transition to my developers and sysadmins by promising them "don't worry you'll be able to edit the XML" (because I found the excellent Invisible Ink plugin before we were willing to migrate). It's the ability to edit the XML that has thus far prevented total mutiny. The safer and more accessible you make editing the XML the more you'll appease your techie user base.

          A lot of smart people have put a lot of smart thought into the XML standards and the ecosystem for XML is very rich. Validation is where the rubber meets the road for many of those tools, so if you provide a DTD or XSD you'd be opening up a vast and powerful array of creative options for your technical user community. The use case above (using a validating editor on WebDAV files) is just the tip of the iceberg, I'm certain smarter people than me will think of other cool stuff to do.

          And wouldn't it actually help your internal development (think Test Driven Design) to have a DTD/XSD? Even if your internal storage format is a moving target, move your formal testable spec along with the target! You'll end up with extra unit tests for free. Worried about migrating content? Maintain a repository of versioned DTDs and use them to identify which format version existing content conforms to! There's a lot of VALUE for you in adopting validation internally, it isn't just about costs. Furthermore, in terms of documentation, we all know that documentation that is generated from or inline with executable testable code is always going to be more up to date and correct than documentation that sits elsewhere on a server. Documentation is a liability unless it is associated with executable verifiable code. If you generate your format docs from your validation spec you'll know that the docs always reflect reality because when you change reality you'll have to change the validation spec. That's agile! That's valuable.

          But I do understand the tradeoffs. I understand that absolute top priority right now is fixing the myriad of browser bugs that make the RTE fundamentally unusable. I understand that we technical users are a small percentage of your user-base. I just hope that after the immediate "OMG THE HOUSE IS ON FIRE" bug fix-a-thon is wrapping up that some effort will be put into formalizing the storage format validation/specification. It'll be good for you. It'll be good for us. It'll enable cool creative unexpected use-cases to be explored without danger of hosing the internal data.

          1. Anonymous

            My use cases for having an XSD/DTD are (most have already been mentioned, just lending a voice):

            • I want to be able to use my own XML editor and utilize 'standard' features such as autocompletion and validation.
              • Because I want to avoid having to read through documentation to know what is valid and what is not, I want an XSD/DTD. I have no intention of reading it instead of the morning paper.
            • I want to know that changes I have made in the underlying XML are valid and supported over and above the fact that it appears to render correctly. For example, if I make a change and confluence updates their storage format how do I know that changes I have made will remain valid as Confluence changes over time? If a new version of Confluence invalidates my storage ‘hack’ how do I know that it will be transformed correctly? If I need to transform them myself, how do I know how to do that?
            • I would like the ability to convert between Confluence XML and another XML format programmatically and know that my changes are valid before pushing them into confluence.

            Conversely, if all you gave me was an XSD/DTD, I have to ask, what use cases would I have for the Advanced Editor? Off the top of my head, I have to say, none. Am I missing something? Has anyone got a reason for using a Confluence XML editor instead of their own? Especially if WebDAV (or similar) is enabled to make accessing the source seamless.

            In our organization, I can't imagine many users will engage in XML editing (either with XSD/DTD if one becomes available or using the Advanced Editor). However, every single user will be impacted by what we will or won't be able to do with your XML. And the long term viability of Confluence will certainly be affected by [the lack of] this capability.

            Rafael.

             

             

          2. Enable the ability to preview XML editor content via an XSLT transform to renderable XHTML

            If you're referring to an "external" XML editor (rather than the Confluence Source Editor plugin), the DTD .zip I've made available for download includes an XSLT stylesheet that does this. However, the stylesheet makes no attempt to render ac:* and ri:* elements in the same way as a Confluence preview... rather, it renders all of these elements in a similar manner to the way that the Confluence rich text editor displays ac:macro elements.

          3. If our devs could edit wiki pages in Eclipse they would be in heaven.

            Zach, I've just installed Eclipse JEE Indigo SR2, imported the contents of my confluence-schema.zip into a project, and am now playing around in the Eclipse XML editor with an example page (specifically, confluence-page-example-with-xslt.xml) from that .zip.

            I've got an XML editor source view open next to a Web browser view of the same file; that is, XML side-by-side with a "preview" (a Confluence rich text editor-like display; not the same as a preview in Confluence, because this XSLT-driven "preview" does not - currently - attempt to render ac:macro elements beyond what the rich text editor does).

            Tip: If, after clicking the thumbnail, the larger image is not quite full-size (for example, the text is not sharp), right-click the larger image, and then click View Image.

            Refreshing the Web browser view is currently clumsy, however: you need to save the XML source (Ctrl+S), and then refresh the Web browser view (F5). I'm no Eclipse guru, but I imagine there would be ways to make that easier.

            Other XML-related views I have open at the same time: Content Model, Documentation, Outline.

            The Eclipse XML editor provides validation and content assist (autocomplete) with context-sensitive help, as you'd expect, and this is nice, but it's based on the DTD rather than the XSD; for example, the help comes from comments in the DTD, rather than the (richer, or what I plan to be richer) annotations in the XSD. I'd like to be able to instruct the editor to use the DTD only for resolving entities, and to use the XSD for validation/content assist/help etc.

            If I remove the DOCTYPE (with its reference to the DTD), then the editor uses the XSD (which is what I want), but that's not a solution, because the DTD is required to resolve any character entity references (such as &nbsp; ); the XSD cannot be used by itself to validate a document (that contains character entity references).

            I've Googled for tips on how to change this behavior, so far with no luck. Any ideas? I'm wondering if the editor exposes this behavior as a property value that I can set, but I've not delved that far yet.

            While Googling, I stumbled across Vex:

            http://wiki.eclipse.org/Vex

            http://www.eclipse.org/vex/

            http://eclipsehowl.wordpress.com/category/vex/

            another free Eclipse plugin for editing XML. Looks interesting enough for me to give it a try when I have time.

             

             

  36. Atlassian, please add the ac:queryparams attribute of the ac:image element to the - I'm not going to use the "c" word (wink) - documentation on this page.

    For example:

    <ac:image ac:queryparams="effects=drop-shadow">
  37. I've updated the draft DTD .zip:

    • Updated: DTD (refined after further experimentation to see what markup the rich text editor can create)
    • New: example Confluence page source file (containing a variety of markup; open this in your favorite validating XML editor), with a variant that refers to an XSLT stylesheet (below)
    • New: "Confluence to XHTML" XSLT stylesheet (confluence2xhtml.xsl)

    Tip: Try opening confluence-page-example-with-xslt.xml in Firefox.

    I'll add a readme file soon.

  38. Atlassian,

    Why do you prefix the attribute names in your ac:- and ri:-prefixed elements?

    From the W3C Recommendation "Namespaces in XML 1.0":

    Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.

     

     

  39. Progress over the weekend: I now have a set of W3C XML Schema 1.0 (.xsd) documents that are (intended to be; I'm still doing some testing) functionally equivalent to the DTD I recently made available. (Except, that is, for character entities - referenced by, for example, &nbsp; - which you can't define in an XSD.) I'm also playing with some XSD-to-XHTML transformation options (for producing schema documentation); I want to do this myself, and get some feedback (and then apply corrections), before perhaps bugging the owner of www.schemacentral.com to host the documentation (as mentioned in an earlier comment).

     

    1. Unfortunately, the doc on schema central would not list the language details for the core atlassian macros, would it? Nor would your XSD validate the content of any macro elements, would it? If so, isn't this community workaround of limited value? I'm not saying "no value", don't get me wrong. (smile) But I wouldn't want to say to my internal users who prefer to use 3rd party editors (and yes, I have some of those): "Here's an XSD you can use and be confident that you won't check in any broken code."

      I feel like the primary usefulness of what you've done so far in this regard is to keep Atlassian honest and perhaps apprise them of some bugs in their implementation? But not necessarily to produce something that end-users can rely on to support editing in XML-capable 3rd party editors or to validate XML that they generate from other integrated workflows?

      1. Shannon, you are absolutely correct on every point.

        Personally, I find the DTD (and corresponding XSDs, that I have not yet made publicly available) valuable for editing Confluence page source with validating XML editors. My reasons include (I know you know all of this; this is for the benefit of other readers who might not be so familiar with XML):

        • The "nice" editing features that this setup enables, which vary depending on the particular XML editor, but which typically include:
          • Selection lists of elements that can be inserted at the current cursor position
          • Autocompletion (including automatic insertion of required elements and attributes)
          • Online documentation (gleaned from the annotations in the schema)
        • A benefit of validation: protection from stepping outside the bounds of the Confluence storage format vocabulary. That is, protection from inadvertently introducing markup (perhaps by copying'n'pasting "true" XHTML source from an external source) - such as a definition list - that is not supported by the Confluence storage format, and that might be stripped by the Confluence rich text editor.

        With regard to macros, you use the phrase "limited value" to describe this community workaround (by which I think you mean: the DTD/XSDs, and any documentation generated from them; such as the type of documentation hosted on Schema Central). I would go further: I would use the phrase "almost no value" or "close to worthless".

        For macros, all the DTD/XSDs do - all they can do - is ensure that the ac:name attribute of the ac:macro element is present, and constrain its child elements to the general structure common to any macro (that is, a combination of zero or more parameters - one of which, a "default" parameter, can be unnamed - and a plain or rich-text "body"; all of which are optional).

        Again, I know you know this (the following explanation, up to the "Idea" heading, is for other readers who might not): all macros look the same to the DTD/XSDs. This is because XSDs (W3C XML Schema 1.0 documents) cannot constrain child elements based on the value of an attribute of the parent element. (I believe the same to be true of DTDs.) The Confluence storage format uses the value of the ac:name attribute of the ac:macro element to identify macros. For example:

        <ac:macro name="macroname">

        where macroname is the name of the macro.

        In an XSD, there is no way of expressing the constraint, 'Allow only this markup inside <ac:macro ac:name="code">, and allow only this (different) markup inside <ac:macro ac:name="section">'. (Other, less widely implemented schema languages, can express such constraints.)

        If, instead of using an attribute value to distinguish macros, Atlassian had chosen unique element names for each macro, the situation would be different. (In case Jens is reading this: I am not about to suggest completely getting rid of the "generic" <ac:macro ac:name="macroname">...  I do understand the points that Jens made in earlier comments on this page.)

        An idea: Temporarily convert macro markup to a structure that supports macro-specific validation

        Here, for the purposes of the idea I am about to describe, I am treating the current Confluence storage format - in particular, the syntax of the ac:macro element, including its ac:name attribute - as a "given"; a constraint.

        Suppose that, in the Confluence Source Editor plugin, you have the source of a page that you want to edit in your favorite desktop validating XML editor.

        You copy the source from the plugin and paste it into your editor. Immediately (as I've described in earlier comments), you have a problem: the source is an XML snippet, not an XML document. You need to wrap it in a root element.

        So, before you can begin editing Confluence page source as an XML document in a validating XML editor, you need to do something to it.

        Maybe (this is my plan, and, although it's related to the idea I'm about to describe, it's not the idea itself), you have an editor-specific macro (perhaps invoked by a keyboard shortcut) that copies the contents of the Clipboard (the snippet copied from the plugin) into a new document, wrapped in a root element (with an XML declaration and DOCTYPE). And maybe you have another macro that copies the "unwrapped" snippet into the Clipboard, for pasting back into the plugin.

        Here's the idea: Suppose that you add one more step to that initial "wrap" macro. Suppose that you convert all occurrences of:

        <ac:macro ac:name="macroname">
        ...
          <ac:parameter name="parmname">...</ac:parameter>
        ...
        </ac:macro>

        to:

        <macro:macroname>
        ...
          <macro:parmname> ... </macro:parmname>
        ...
        </macro:macroname>

        where the "macro:"-prefixed namespace has a corresponding XSD (or equivalent definitions in a DTD) that defines the contents of each macro, including their specific parameters (whether required or optional), the specific values allowed by those parameters (for example, numeric? string? URI? specific date format? something yet more specific?), and annotations (displayed by the XML editor as online documentation, and that would also appear in XSD--to-XHTML documentation such as that displayed by Schema Central).

        (A possible wrinkle: perhaps - again, with reference to earlier comments by Jens - I don't mean all occurrences of <ac:macro>. Perhaps I mean: those occurrences of <ac:macro> with ac:name attribute values that have a corresponding macro-namespace element definition in the XSD. That is, "known" macros.)

        The XML editor would then be able to use the XSD to help you code valid macros according to the specific syntax of each macro.

        The subsequent "unwrap" macro would convert the "macro:" elements back to their original Confluence storage format markup, prior to pasting the source back into the Confluence Source Editor plugin.

        I haven't yet had time to look at the list generated by Scott Dudley's plugin (I hope to get the time this week), but, I, too, can envision this:

        an entire DTD [...] that corresponds to all of the entities that are available for a specific Confluence instance, including macros, and presumably integrating the groundwork that Graham has already laid.

        I am hoping that it might be possible to programmatically convert Scott's list into a DTD/XSD. We'll see.

        (In practice, I might consider implementing these macros - or parts of them - in XSLT stylesheets.)

        Your thoughts?

        Bear in mind that I have treated the current Confluence storage format as a constraint: I am not, in this idea, proposing that Atlassian changes the storage format. It is regrettable that Atlassian appears not to have spent much time thinking about how the storage format might be validated - for example, taking into consideration the limitations of popular schema languages when designing their markup - but that is deliberately outside the scope of this particular idea.

        P.S. If anyone thinks that this idea has any merit - I fear some might consider it, with some justification, too "tricksy" - then we can discuss implementation detail such as macro-specific names for parameter elements (<macro:macroname-parmname>, versus just <macro:parmname>).

        1. Some of us prefers it that way, essentially if you begin to validate into macro's structure, it would mean I had to carry around up to 4+ different XSD's or DTD's not to mention when I transport data from installation A to installation B to C or D... Also meaning that I would have to "update" those schema between updates.

          And at the end of the day, if you can't include every possible macro combination (version combinations as well, and you can't, because how could you possibly know of all the macros in the world?). then well... Deep macro validation will make the DTD/XSD unuseable to me.

          Basically limiting my workflows between multiple instances.

          So I can only vote "NO" to validation of specific macros.

          If you do this, at least make it VERY clear what I need to strip out in order to get the generic macro validation

          In any case, as long as this is a 3rd party XSD/DTD then i don't have to worry about Atlassian beginning to use it for validating input, meaning I can keep doing what I do, so in that forum I won't yell as high about it as I would otherwise, because I can essentially ignore the contribution. It would be nice to be able to use it however.

           

          1. Currently, this idea is really only a thought experiment. I'm not actively coding it.

            If you do this, at least make it VERY clear what I need to strip out in order to get the generic macro validation

            Yes, this issue - retaining support for generic macro validation - did occur to me, although I did not refer to it in my previous description.

            My plan - in so far as I have a plan for implementing this idea, which is not very far at all - would be to continue to support the generic macro validation, and specifically not have to strip anything out to get it back.

            That is, the <macro:macroname> et al markup would be something you could choose to use, or not.

            how could you possibly know of all the macros in the world?

            Of course, you're right, I couldn't. I had this issue - and you (wink) ! - in mind when I wrote the following (in particular, the text highlighted in green):

            A possible wrinkle: perhaps - again, with reference to earlier comments by Jens - I don't mean all occurrences of <ac:macro>. Perhaps I mean: those occurrences of <ac:macro> with ac:name attribute values that have a corresponding macro-namespace element definition in the XSD. That is, "known" macros.

            ("Known" to the XSD generated using the listing from Scott's plugin... at least, that's the idea.)

            One concern I have about this idea - relating to its "tricksiness" - is that users who have not yet had their morning coffee might forget to convert the temporary macro: markup back into the original ac:macro markup, and paste page source laced with temporary markup back into the Confluence Source Editor plugin. I would not wish to be held responsible for the results!

            1. My plan - in so far as I have a plan for implementing this idea, which is not very far at all - would be to continue to support the generic macro validation, and specificallynot have to strip anything out to get it back.

              In the case of this, no complaints at all (smile)

          2. I might as well come clean: one of my reasons for describing this idea is not necessarily to implement it myself, but to illustrate to Atlassian (if any Atlassians have the time and inclination to read it) some issues with the current markup (specifically, use of attribute values, rather than element names, to distinguish macros; although I realize this design might have been modelled on the XHTML object element), that Atlassian might choose to consider when designing new markup or changes to existing markup.

             

  40. I've replaced confluence-dtd.zip with confluence-schema.zip.

    Changes:

    • Added a readme
    • Refined DTD after testing against Atlassian's own Confluence Documentation source
    • Added XSD (constraints match DTD, as far as possible)
    • Added catalog and related sample files

    For details, see the readme.html file in the .zip.

    This is a work in progress. I am awaiting answers from Atlassian to several questions that might affect the DTD/XSDs.

    Feedback welcome.

  41. Developing those DTD/XSDs burned some midnight oil, so I hope that readers of this page will briefly indulge me here...

    What's in a name? The term "Confluence storage format" works in the sense that "it is what it says on the tin" (if you allow that there's an implicit "page/blog post" qualifier in there somewhere), but, having used this term for a while now, I feel that it's clumsy and too long. (Compare "Confluence storage format" with, for example, "DocBook" and "DITA"). I can live with this existing term, but if I'm going to be spending more time with the language (it seems likely), I'd prefer a shorter, sweeter-sounding name. (I realize "sweeter" is a subjective judgement.)

    The first name that occurred to me was "Confluent": that is, to appropriate the adjective "confluent" as a proper noun. Then I did a trademark search: I found no "live" US trademarks for just the one-word "Confluent", and certainly not in this market space, but there are several (mostly medical) companies that use the word "Confluent" in their names. So, maybe it's a contender. One point in its favor is that you could just refer to "Confluent", or, if the need arose, firmly place it in context by appending the word "XML" - so, "Confluent XML" (getting longer, though) - returning "confluent" to its roots, albeit with a capital C, as an adjective.

    Then I saw that "conflux" was a synonym for "confluence", and it occurred to me that its trailing letter x had potential. "Confluxml" (lowercase "ml")? "ConfluxML" (uppercase "ML")? Currently, I think that these are my favorites; I can't quite decide between the two, although I somehow find it appealing that "ConfluXML" begins with the same letters as "Confluence", and the uppercase "XML" provides a clear break. (Pronounced - regardless of whether it's spelled "...ml" or "..ML" - "conflux em el".)

    Google "conflux":

    Your search - "confluxml" - did not match any documents

    Looks like a winner to me!

    Then again... maybe something more prosaic, such as "Confluence page XML" (where "page" is used here in a generic sense intended to encompass "blog post").

    Some candidate terms (including the "incumbent"):

    • Confluent
    • Confluxml
    • ConfluXML
    • Confluence XML
    • Confluence page XML
    • Confluence source (another sort-of incumbent, but I would argue that this term is too ambiguous, unless it's used strictly in context: I think of "Confluence" as software, and "Confluence source" as the source code for that software)
    • Confluence storage format

    Opinions? ("Why bother?") Other suggestions? (I'm half-expecting a collective yawn (wink) ) I certainly don't want to spend too much time on this.

    Finally, I'm not looking for a term that I would expect general Confluence users to see, or even be aware of. For example, I'm not about to propose that Atlassian renames the "Confluence Source Editor plugin" to, say, "ConfluXML Editor plugin". I'm really just after something pithy that I can use in comments on pages such as this, and in the DTD/XSD documentation (the readme.html), instead of the rather unwieldy "Confluence storage format".

     

     

    1. I Referred to it as CML at some point (Confluence Markup Language)

      1. Yes, short and sweet, but, unfortunately, CML is already used for an XML vocabulary: Chemical Markup Language.

        Although, you could argue, this is not in the same "application space" as Confluence - documentation versus chemistry - simply being another XML vocabulary - so, in the same "space" in that sense - rules it out for me.

        1. Well you could be cheesy then and add an A for the company: ACML (Atlassian Confluence Markup Language), even AML might make sense if they embed it in Jira as well...

          Although ACML begins to sound like something from a bad song, and AML is just... odd... somehow... 

  42. A nit in the readme.html of that XSD/DTD .zip: I realize I haven't quite got the XSD aspects of the catalog-related tips quite right. Specifically, I can't get any XML editor to use the XSD for validation unless the document contains a schemaLocation attribute. I'm clearly missing something. The XML editors (specifically, jEdit and Altova XMLSpy 2012) use the same catalog.xml to map a DOCTYPE FPI to the DTD file just fine. And, as described, I can specify the xmllint --schema command-line option to use the XSD for validation, whether or not a document contains a schemaLocation attribute.  Any ideas?

     

  43. I have just sent the following email to the XML-DEV mailing list:

    To:      xml-dev@lists.xml.org,
    Date:    20/04/2012 04:30 PM
    Subject: Request for review: DTD/XSDs for the Confluence Atlassian 4 storage format

    From my earlier email:

    > [I am] hoping to learn more. And I am prepared to publicly expose my ignorance to do so

    On that note...

    I am a user of Atlassian Confluence, a commercial wiki product. I have no other affiliation with Atlassian, (Okay, I'm Australian, too.)

    Previous (3.x) versions of Confluence stored content in a wiki markup format. The current version of Confluence (4) stores content in a proprietary XML vocabulary that consists of:

    - Elements and attributes that have the same names as a subset of elements and attributes in XHTML 1.0 (mostly from XHTML 1.0 Strict, with a few additional elements from XHTML 1.0 Transitional). Elements in the Confluence XML vocabulary that have the same name as elements in XHTML 1.0 have a much more limited set of attributes than the XHTML 1.0 elements of the same name.

    - Proprietary elements and attributes

    Some Confluence users have asked Atlassian to provide a schema (DTD, XSD, or both) for this XML vocabulary. However, Atlassian has indicated that providing a DTD/XSD is not high on its list of current priorities.

    So, I have attempted to create the DTD/XSDs myself, based on a combination of:

    - The XHTML 1.0 Strict DTD (and a few snippets of Transitional)
    - The documentation that Atlassian has provided (which falls far short of the detail required to develop a DTD/XSD)

    - Experimentation with the Confluence rich text editor (to exercise the full range of markup that the editor can generate)

    - "Forensic analysis" of the XML source of Atlassian's own Confluence documentation (Atlassian publishes "exports" of their public documentation, containing the XML source of over 4000 pages; so, a reasonable-size test bucket) - xmllint was very useful here for automating validation, and iteratively refining the constraints of the XSD/DTDs

    I hope I'm not breaking any mailing list guidelines here (I don't think so; I've just re-read them)...

    I welcome feedback (constructive criticism) of these DTD/XSDs.

    I'm not offering any money, so feel free to have fun at my expense by flaming these files, and my questionable XML skills, to a cinder. Perhaps a phoenix will rise from the ashes ;-).

    You can download the package (a 30 KB .zip file) from:

    http://www.amnet.net.au/~ghannington/confluence/confluence-schema.zip

    For details, see the readme.html in the .zip.

    I am aware that the tips in the readme on "Using a catalog, rather than explicitly referring to the DTD/XSD in each document instance" are, at best, incomplete... I'll fix this in the next couple of days, with thanks to Liam for his recent advice (on this mailing list).

    I hope that the above address will be a temporary home for this package; I hope that Atlassian will soon either render the package obsolete by providing their own - although I think that's unlikely, given its stated priorities - or take ownership of this package.

    Graham Hannington
    Perth, Western Australia

  44. Hallo all

    We're planning to document the markup for all macros shipped with Confluence. For each macro, the documentation will define the macro name, parameter names, accepted parameter values, default value, and whether the parameter is required or not. We'll document both the wiki markup and the xHTML-based storage format for each macro.

    Here's the tracking issue: CONF-24972 - Getting issue details... STATUS

    I've started the document design and prototyping. We're giving this task high priority, although there are other high priority tasks too. (smile)

    Cheers, Sarah

    1. Thank you. It is now very likely that my enterprise will be able to migrate to 4.x instead of staying indefinitely on 3.5.x and discontinuing all maintenance renewals. I'm glad to see that my efforts to help you understand why this information was needed weren't in vain.

  45. Atlassian,

    Now that you can view the schema in a human-readable format (see the link in my previous comment), I would really appreciate it if you could answer my remaining questions (in my earlier comment, based on analysis of the 4000+ pages in your Confluence Documentation export), regarding, for example, style and class attributes on various elements, and the presence of div elements. I'd like to get these issues cleared up before I ask the owner of Schema Central to host the documentation. These issues with the formal definition of the storage format (in this case, the XSD) are easier to see when you can view the formal definition in a human-readable format.

    For example, despite the presence of the class attribute on various elements in your source (see my earlier comment), I think that the only way to get the rich text editor to create a class attribute (please correct me if I'm wrong: all I have to go on is my own observations) is to highlight table contents (class="highlight" on td and th; I've not seen it on a tr). Currently, as you can see in the schema documentation, the XSD allows the class attribute on the following elements (based on earlier analysis of my local "sandbox" source): a, br, td, th, ul. I'm now wondering whether, despite the presence of the class attribute on various elements in actual source, I should restrict the DTD/XSDs to allowing the class attribute on only the td and th elements (that can have class="highlight" applied by the rich text editor).

    (Why I'm bothering with this level of detail - and repeatedly asking for clarification from Atlassian, when it has clearly stated that its current priorities lie elsewhere - is another matter entirely. Something like, I guess: since I've started, I might as well do it right, and I figure it doesn't cost Atlassian much time to answer these questions.)

     

    1. Graham, you can also get the class attribute (and many others) by copy and pasting content from other web pages.

      I noticed in your schema that you have quite a restricted set of XHTML elements and attributes. I guess you based it on what you have observed.

      The thing to watch out for is that we are developing to the full XHTML spec. Just because we don't have a mechanism to create certain XHTML elements or attributes yet doesn't mean that we won't enable new formatting options in a subsequent release. Likewise the wiki migration result in some cases will have elements or attributes that you can't access through the Editor yet. We don't migrate this data away because at some point in the future we will add Editor support.

      It really comes back to something we have mentioned a few times before. The documents you can create with the Editor are only a subset of the documents that you can represent and display in Confluence. You could quite definitely have one schema representing what the Editor can do (which I think you have created) and one representing what Confluence can store and display. The latter will be a lot more like the stock XHTML schema (but still different).

      Some of our earlier experiments with creating schema were based on modifying the stock XHTML schema and experimenting with XHTML Modularization if that provides you with any insight into our thinking.

       

      1. Hi Paul,

        Thanks again for your response, and for your insights into Atlassian's thinking.

        From your comment:

        I noticed in your schema that you have quite a restricted set of XHTML elements and attributes. I guess you based it on what you have observed.

        Yes and no. Your guess is true to some extent, but not entirely so. Earlier on this page, I asked the specific question:

        What subset of XHTML does Confluence support?

        to which Bill Arconati (Atlassian) replied:

        The documentation in this page is already comprehensive

        I based the schema (that is, the DTD and equivalent XSDs) on Bill's reply, which mostly (with the exceptions that I have noted, and have asked about in comments on this page) matches my own observations (including 4000+ pages of Atlassian's own Confluence Documentation).

        From your comment:

        The thing to watch out for is that we are developing to the full XHTML spec.

        Yes, that would be something to watch out for. To my knowledge, this is the first time that Atlassian has mentioned this. That information would have been helpful to me earlier. Either when Bill gave his "comprehensive" reply, or before.

        I and others have already asked the following question, to which Atlassian has so far not replied: which XHTML spec? XHTML 1.0 Strict? The elements documented on this page also include some from XHTML 1.0 Transitional; the elements s (strikethrough) and u (underline).

        From your comment:

        one schema representing what the Editor can do (which I think you have created) and one representing what Confluence can store and display. The latter will be a lot more like the stock XHTML schema (but still different).

        Interesting. According to Bill:

        Any tags you don't already see documented on this page will likely get removed when you save the page.

        Literally concatenating your comment and Bill's (that is, two statements from Atlassian) results in: "[You:] what Confluence can store and display ... will be a lot more like the stock XHTML schema ... [now, Bill:] Any tags you don't already see documented on this page will likely get removed when you save the page". Is it just me, or do you see a problem here?

        From your comment:

        Some of our earlier experiments with creating schema were based on modifying the stock XHTML schema and experimenting with XHTML Modularization if that provides you with any insight into our thinking.

        Thank you. That provides me with some insight, but not a lot. I had previously read that W3C page "XHTML Modularization" when researching the best way to develop the Confluence DTD/XSDs. However, when I compared the "comprehensive" documentation on this page to the XHTML schema (without the insight that you've just given me: "we are developing to the full XHTML spec"), and considered the number of redefine elements I'd have to use to restrict/extend the XHTML schema modules to match, I opted to modify a copy of the "stock" XHTML 1.0 Strict XSD, as you've seen (and as I've described in the comment header).

        Sigh... developing these DTD/XSDs has been an interesting little project: no one pushed me to do it, and I believe it still has value, as far as what the rich text editor currently supports, in the absence of any DTD/XSDs from Atlassian. And perhaps it's even been valuable simply to prompt conversations such as this, which have revealed new (at least, new to me) insights into Atlassian's thinking ("we are developing to the full XHTML spec"). I hope you can understand my negative feelings about Bill's "already comprehensive" response. And I'm curious to know whether Atlassian sees any problem with, as it (a combination of you and Bill) has stated, Confluence storing tags that will likely get removed when users edit pages in the rich text editor. (Or is the use of  "likely" here in some way similar to the use of "comprehensive"?)

        Thanks again for another illuminating response, Paul, much appreciated.

        1. Hi Graham.

          It is hard to be confident about reading emotions via text (regardless of how rich!) but I think you are feeling that I have rubbished or undermined your efforts here. That was not my intention at all. Yourself and many others have been very clear that you need the schema and DTD and what you have produced is to my eyes a good representation of Confluence storage format as it stands today.

          Likewise, the documentation Bill has created here is a pretty accurate description of storage format, but in a different format.

          Because the implemented code is the ultimate source of truth there will always be slight loss in the telling as you go from 'code' → 'developer explaining code to PM' → 'PM writing this up in Confluence'(1). But there is nothing wrong with what Bill has documented. This document's intended audience is stated as -

          ...developers and advanced users who need to interpret and edit the underlying markup for a Confluence page or blog post.

          I think the intended audience of the schema and DTD will be different.

          Over time, as we further develop the capabilities of the editor, we will need to further developer Confluence storage format. We strive to use the pre-existing capabilities of XHTML wherever possible with storage format. We certainly won't constrain development to just the XHTML tags that are documented on this page. In addition the wiki migration code was not constrained to only output tags and attributes that our Editor can currently produce. The primary goal with migration code was not to lose fidelity.

          So the point I'm trying to make with "...we are developing to the full XHTML spec" is that your schema documentation (and this page) will need to be updated along the way. As with all documentation it is true at a certain point in time and then there is a cost in keeping it as true as you can moving forward. We are grateful that you have committed to this cost - I'm joking! (smile)

           

          (1) This is not a slight on Bill: the same loss of accuracy happens in reverse: 'PM writes spec' → 'developer implements something a little bit like the spec' → iteration 2 → 'something a little more like the spec' → repeat

          1. Hi Paul,

            Thanks again for the continued correspondence, I appreciate it. I'm comfortable with the idea that the storage format will evolve and expand.

            Do you have any response to the following specific issue, from my previous comment:

            Literally concatenating your comment and Bill's (that is, two statements from Atlassian) results in: "[You:] what Confluence can store and display ... will be a lot more like the stock XHTML schema ... [now, Bill:] Any tags you don't already see documented on this page will likely get removed when you save the page".

            I see a problem here. Do you?

            For example, from your comment:

            We don't migrate this data away because at some point in the future we will add Editor support.

            You'd better not edit pages containing such data (markup) before that point, then, because otherwise, according to Bill's statement, that markup will likely get removed when you save the page. The editor will "migrate this data away" for you.

            1. I see a problem here. Do you?

              I don't really see a problem here but I will have a go at trying to help. I think you might be worried about the Editor mangling certain pages?

              Our Editor is basically TinyMCE. TinyMCE is an HTML/XHTML editor and does try to follow the XHTML spec as much as possible. What TinyMCE will tolerate is configurable and on top of that we also have made many customisations.

              You will probably find that as a content creator most valid XHTML will be tolerated by TinyMCE. There are some exceptions especially around the area of security (script tags, etc). You should also find that most valid XHTML will be stored unharmed by Confluence.

              This is the reality. But if you asked us what we will guarantee to work at this point in time then it is what Bill has documented here. And where these things that Bill has documented don't work then we have a bug to fix.

              However, should you raise an issue that <thead>tags were being stripped then we are unlikely to give that much priority at the moment. The stance would be something like "you have been warned". Perhaps in the future we start to "fancy up" further the things you can do with tables then we might start to explicitly use the <thead> tag and it then becomes something we should document here.

              (Incidentally, <thead> will happily make its way in and out of the Editor and the database but not because of any specific handling on our part. We don't have any code that cares about it - we just tend to leave XHTML we don't explicitly care about unmolested. While our use of the term XHTML has been heavily criticised the XHTML spec actually is a very good resource for understanding something like 84% of Confluence storage format.) 

              1. I think you might be worried about the Editor mangling certain pages?

                For this specific case (what I'm specifically worried about here), I would replace "mangling" with "remove data from". I'll try to clarify what I mean.

                From you:

                We don't migrate this data away because at some point in the future we will add Editor support.

                From Bill:

                Any tags you don't already see documented on this page will likely get removed when you save the page

                I'm simply quoting you and Bill, and pointing out a potential issue: Bill says the editor will "likely" remove data that you say you want to keep. In practice, however, perhaps this isn't an issue: as you say, the truth is in the code.

                1. I see. Well my advice would be to trust Bill's sage advice (smile)

                  Don't count on anything beyond what Bill has documented. I have probably over-shared and caused confusion - that's a lesson learned and I apologise.

  46. I have developed a rudimentary working XSLT stylesheet that transforms Confluence XML page source (wrapped in a document root element) into Confluence 3.x wiki markup.

    The stylesheet handles headings, paragraphs, lists (including nested lists), text effects (for example, it converts decimal RGB color values into a hex string for the color macro), text breaks, tables, macros (still finessing/testing this, but it works for the several types of macro I've tested, including, for example, code and section/columns), images, emoticons, and some types of links (still working on this).

    Looks promising so far (I only started developing it this afternoon), at least for my use case, which is to copy relatively simple content from Confluence into JIRA. (Although I'm also testing it by pasting into the Confluence 3.x wiki markup editor.)

    More news soon.

    1. That's great news Graham; I'd been thinking along the same lines, and wondering about the feasibility of creating an editor plugin which would use such a transform and the built in wiki->xml migration to allow editing in wiki markup. It's clearly not as clean as confluence v3, but might mean that shops that like using wiki markup could continue to do so. Of course, I'd rather hope that Atlassian would take the work you've already done and produce such a plugin themselves as they're best placed to maintain it, but you've been making huge strides in the right direction on their behalf, and I'm grateful for that.

       

      1. Hi Niall:

        creating an editor plugin which would use such a transform

        Yes, I'm totally with you there. I'm happy to iteratively tweak the XSLT stylesheet to improve it, and provide that as input to the developer of such a plugin (you?), but - while I've considered it - developing a plugin myself would take me more time than I have, and anyway - having never developed a Confluence plugin, and having only ever taken baby steps in Java programming - I am far from the best person for the job.

    2. I've added a comment to the "Confluence 4.0 Editor - Customer Feedback" page:

      Wikifier: Convert Confluence XML to wiki markup

      Wikifier is a web-based test harness for the XSLT stylesheet (confluence2wiki.xsl) I mentioned earlier. Soon, I'll also add the XSLT stylesheet to the schema package (.zip).

      Whitespace handling - especially, restricting myself to XSLT 1.0, and not using an external library of functions (I wanted to keep the XSLT small/concise), and to XSLT that would work in Firefox (which doesn't like recursive templates) - was tricky.

      If anyone uses it, I imagine I'll have some requests to tweak the whitespace handling for specific macros.

  47. Hallo to all the contributors to this page

    I'm planning to "move" this page into the main body of Confluence documentation. It won't go far – it will still be in this space on this wiki. At the moment, it's buried under Confluence 4.0 Editor - Customer Feedback, which is in turn a child of Planning for Confluence 4.0. In the next few days, I'll move it into the Confluence User's Guide, under a new section called "Advanced Uses of Confluence".

    So, why did I put quotes around the word "move" in the previous paragraph? Well, the aim is to move the information about the storage format into the user's guide. But we want to retain all the comments on this page, and at the same time make sure that people reading the core information about the storage format can load the page without the long tail of comments.

    To make that happen, I'll rename this page to "Feedback on Storage Format". The new page in the user's guide will be named "Confluence Storage Format". It will have the same content as this page (by dint of content reuse) but will start out clean of comments. (wink) The comments are great, but we'd like the page to focus documenting the current solution. I'll add a note on the new page, directing people to this page for discussion and new ideas.

    1. Hi Sarah,

      Please let me know if you would like me to change my commenting "habits". Looking back at the long tail of comments on this page, I see some long code listings that perhaps might have been better as links (it's a shame that comments can't have attachments... then again, perhaps I should just get onto Bitbucket).

      but we'd like the page to focus documenting the current solution.

      Could you clarify that (maybe you will in the body of the new page)? I don't want to annoy you (Atlassian) by adding comments to the wrong page.

      For example, would comments about the schema (DTD/XSDs) that describes the current solution belong on this (old) page, or the new page?

  48. Could you please update this page with the new-for-4.2 use of <div> elements for visual page layouts? (And any other new markup not yet documented on this page?)

     

    1. Atlassian,

      I don't want to annoy you by adding the same comment to two pages. I think my previous comment now belongs on the new Confluence Storage Format page. Would you like me to create a new copy of that comment on the new page?

       

    2. Hallo Graham

      Thank you for pointing out this gap. I've raised an issue requesting the documentation here: CONF-25415 - Getting issue details... STATUS

      I'll alert the development team to the request.

      Cheers, Sarah

       

  49. The new, proprietary data-atlassian-layout attribute on div elements

    Based on this request on the new Confluence Storage Format page:

    If you have feedback on the Confluence markup ... please add your suggestion to the page titled Feedback on Confluence Storage Format.

    I think/hope the following comment belongs here...

    I've just been playing with the new-for-4.2 "Page Layout" feature, and looking at the corresponding XML source generated by the rich text editor.

    For example:

    <div class="contentLayout" data-atlassian-layout="{&quot;name&quot;:&quot;pagelayout-three&quot;,&quot;columns&quot;:[&quot;&quot;,&quot;&quot;,&quot;&quot;],&quot;header&quot;:true,&quot;footer&quot;:true}">
      <div class="header">
        <div class="innerCell">
          <p>Header</p>
        </div>
      </div>
      <div class="columnLayout threeColumns">
        <div class="cell ">
          <div class="innerCell">
            <p>Column 1 of 3</p>
          </div>
        </div>
        <div class="cell ">
          <div class="innerCell">
            <p>Column 2 of 3</p>
          </div>
        </div>
        <div class="cell ">
          <div class="innerCell">
            <p>Column 3 of 3</p>
          </div>
        </div>
      </div>
      <div class="footer">
        <div class="innerCell">
          <p>Footer</p>
        </div>
      </div>
    </div>

    I'm curious about the new, proprietary data-atlassian-layout attribute (on the highest-level div element in the example above).

    I think that this is the first time that I have seen, in the Confluence storage format, a proprietary Confluence (or, if you prefer, Atlassian) attribute on an element that has the same name as an XHTML element.

    Paul Curren (Atlassian) has previously made the following statement:

    we are developing to the full XHTML spec

    I realize that the letter of Paul's statement does not preclude adding proprietary attributes to elements that are from the XHTML spec. However, I felt it was worth at least mentioning this attribute, based on a combination of the following two factors:

    • The "novelty" of this data-atlassian-layout attribute (that is, it's the first time I've seen in the Confluence storage format a proprietary attribute on an element with the same name as an XHTML element)
    • My - I now realize, probably incorrect - interpretation of the "vibe" of Paul's statement (here, I'm using the word "vibe" in the same sense in which it is used in the Australian movie The Castle)

    I thought, in a hazy, vibe-y kind of way, that, as per all previous cases (of which I am aware), any new uses in the Confluence storage format of elements that have the same name as XHTML elements would follow the rules of the XHTML spec (or at least, in the case of attributes, a "subset" of the full XHTML spec). Specifically, in this case, elements with the same name as XHTML elements would not contain proprietary attributes. Clearly, I was wrong. But I do wonder, since, as I've mentioned, it's the first time I've seen this: are you sure you want to do this? "Yes" is a perfectly acceptable answer. I don't expect to be privy to your design discussions.

    I'm about to update the DTD/XSDs to allow the div element, and to allow this new, proprietary data-atlassian-layout attribute on div elements. (I note that, since you have not namespace-prefixed the data-atlassian-layout attribute, it belongs to the same namespace as the div element. Which is fine, not a problem at all, as far as the XSDs I've developed are concerned, because they already coin a new namespace for elements with the same name as XHTML elements. However, in case it ever occurs to you, this new attribute is one more reason - there are already many others - not to claim that such elements and attributes belong to the XHTML namespace "http://www.w3.org/1999/xhtml".)

    1. Hi Graham. 

      In a nutshell, I think you are spot on with your analysis here and I'm not particularly happy with how page layouts have been represented in storage format. I don't want to be too hasty though because I wasn't involved in the development so I don't have the big picture. There may well be practical reasons for this approach.

      I've raised  CONF-25410 - Getting issue details... STATUS  because I would like to see this addressed. I've raised it on behalf of yourself. If you would prefer your name not to be on the issue just let me know.

      1. Cheers, Paul. No problem with raising the JIRA issue on my behalf, except perhaps for some minor qualms about the wording of the title: I've added a comment to the JIRA issue.

        Chris Maloney has already added a very useful comment to that issue, raising, among other items, the old chestnut of which XHTML spec you are developing to. Might be worth a clarification on this page?

         

  50. 5 stars for the burgeoning Confluence Storage Format for Macros page. This is exactly the level of detail we need. Thanks, Sarah!

  51. My apologies if this has already been covered somewhere in the 40,000+ words above.

    I have thousands of pages of documentation in FrameMaker format that we want to migrate to either Confluence 4.2 or MindTouch Core. (The WebWorks tool is OK for publishing static pages but they're not editable.)

    I've set up a conversion process with MIF2Go that generates XHTML I can paste into Confluence's source editor on a page by page basis. This is better than nothing, but it's a lot of work to re-create the internal cross-reference links.

    I'd like to expand that into something that could convert a whole FrameMaker project into something I can import into Confluence, but I can't find documentation of such a format. What Confluence's XML Export generates is not self-explanatory.

    Is there a documented or human-readable format I can use for this?

    1. Hi Robert,

      Is there a documented or human-readable format I can use for this Confluence XML Export?

      Sort of.

      The closest thing I have found is the "Serialized Form" API documentation provided by Atlassian. For example, for the child element <object class="Page" package="com.atlassian.confluence.pages"> of the document root element of entities.xml, see the documentation for the serialized form of the Page class.

      I strongly suspect (but could still be completely wrong) that the Confluence XML Export is generated by Hibernate, a Java library for persisting POJOs (a description closer to plain English: for saving in-memory Java objects to a file; in this case, an XML file).

      In practice, I have found that inspecting the entities.xml file in an XML editor (such as Altova XMLSpy) is quite helpful. You probably already know some or all of the following, but in case any of it is useful to you, here goes... all of the following is just what I have observed by inspection... it is by no means complete... any errors are entirely my fault...

      Confluence XML Export format

      The Confluence XML Export files that I have seen are .zip files that contain one folder and two files:

      • An attachments folder, containing numerically named subfolders, which contain numerically named files (the attachments)
      • An entities.xml file, containing the page contents and their structure
      • An exportDescriptor.properties file; a (brief) plain text file containing details of the export

      The entities.xml file consists of the root element <hibernate-generic> with multiple <object> child elements.

      These <object> elements have the attributes class and package, referring to the Java objects that these elements represent. That is, an <object class="Page" package="com.atlassian.confluence.pages"> element is a persisted (saved) representation of a Java object of class Page, from the package com.atlassian.confluence.pages.

      In the remainder of this comment, I will use the value of the class attribute of an <object> element to refer to that element. For example, I will refer to the element <object class="Page" package="com.atlassian.confluence.pages"> as a Page (object).

      Each object has a unique numeric ID, represented in the XML as the contents of an <id> child element of the <object> element. For example:

      <id name="id">123456789</id>
      

      In addition to having an ID, objects can contain named properties and collections.

      In the XML, a property is represented by a <property> element whose name attribute specifies the property name, and whose contents specifies the property value. For example:

      <property name="position">9</property>
      

      A collection is essentially a property with multiple values. A collection is represented by a <collection> element with multiple <element> children. The contents of the <element> children contain the collection values.

      Objects required for rolling your own export, to import pages

      Page object

      A Confluence page.

      Properties

      position
      Position of this page among its siblings, reflected in various places in Confluence.

      parent
      ID of the Page that is the parent of this page.

      space
      ID of the space to which this page belongs. This refers to a Space object (<object class="Space"> with child element <id name="id> containing the matching space ID). If the Export is for a space, then the entities.xml file will contain only one Space object.

      bodyContents
      ID of the BodyContent object that contains the contents (Confluence storage format XML) of this page. That is, the Page object does not directly contain its own contents: rather, it refers to a separate BodyContent object.

      title
      Page title.

      [How I miss XHTML definition lists!]

      Other properties:

      • version
      • creatorName
      • creationDate
      • lastModifierName
      • lastModificationDate
      • versionComment
      • contentStatus

      Collections

      Required for rolling your own export:

      attachments
      IDs of the Attachment objects for this page.

      children
      IDs of the child Page objects of this page.

      Other:

      ancestors
      Page IDs of the ancestors of this page.

      outgoingLinks
      IDs of the OutgoingLink objects for this page (links to external locations).

      historicalVersions
      Page IDs of the historical versions of this page.

      labellings
      IDs of the Labelling objects associated with this page.

      BodyContent object

      The content of the body of a page.

      Properties

      body
      This is it! The "payload"; the actual contents of a page; a snippet (that is, no root element) of Confluence storage format XML that is the page contents, wrapped in a CDATA section.

      Tip: To avoid embedded CDATA sections, insert a space in the terminator of any CDATA sections in the page contents, between the two closing square brackets ("] ]>").

      For details on this format, see the Atlassian documentation, and my attempt at a schema.

      content
      ID of the Page object to which this body content belongs.

      bodyType
      Number representing the type of body contents.

      Attachment object

      Maps to a file under the attachments folder in the Export .zip. (I haven't looked into the details of this yet.)

      Space object

      A Confluence space (to which pages belong).

      Properties

      key

      name

      description
      ID of the SpaceDescription object for this space.

      homePage
      ID of the Page that will be the home page of the newly imported (restored) space. If you omit this property, Confluence displays the following error when you view pages in the space:

      The root page @home could not be found in space space title.

      SpaceDescription object

      Properties

      title
      Title of the space. Not sure how this relates to the name property of the Space object.

      Collections

      bodyContents
      ID (I've only ever seen one element in this collection) of BodyContent object whose bodyType property is 0 (no content). Strange.

      Other objects

      BlogPost object

      BucketPropertySetItem object

      (I have an inkling what this is, but can't be bothered investigating in detail right now.)

      ConfluenceBandanaRecord object

      ImageDetailsDto object

      Something to do with image details, I guess. Not looked into this yet.

      Label object

      A label.

      Labelling object

      Maps a Page object to a Label object.

      Notification object

      OutgoingLink object

      A link from a Confluence page to somewhere else.

      ReferralLink object

      A link from somewhere else to a Confluence page. (How visitors got to the page.)

      SpacePermission object

      Something to do with permission to access spaces, I guess. Not looked into this yet.

      Universal Wiki Converter

      Someone else recently corresponded with me about converting from another format to Confluence. I made the unsolicited suggestion that they might want to investigate converting their files into a Confluence export file, just as if it had been created by Confluence, and then import that file into their new system.

      Then, fearing that I might have steered them in the wrong direction, I did some Googling on the subject, and found this, provided by Atlassian:

      https://studio.plugins.atlassian.com/wiki/display/UWC/Universal+Wiki+Converter

      ("Because you have another non-Atlassian system full of existing content that needs to be moved, cleanly."... "The Universal Wiki Converter (UWC) is a standalone application tool that assists in converting content pages from other wikis to Confluence format. It's an extensible framework, allowing users with wikis that aren't currently supported to add their own converters.")

      (I know, Framemaker is not a wiki. I have some limited first-hand experience with FrameMaker.)

      Whether or not you choose to use UWC, its FAQ mentions the bulk upload plugin, which might be of interest to you. Or the WebDAV plugin.

      From the UWC FAQ page:

      This project is undergoing an update, and will be evolving during Q1 2012. Your patience while under construction, please.

      "Watch this space," I guess.

      In the meantime, although I can't promise anything, I might be able to lend you a hand writing - or, er, maybe just offer advice on; I've spent too much time on Confluence lately! - an XSLT stylesheet that would transform multiple (XHTML?) files exported from FrameMaker into a single entities.xml. Let me know how you go.

    2. As Graham is illustrating above, the Confluence XML Export format is a tricky format to deal with. It's not really intended for human consumption.

      I would think your best chance of success here would be to convert your FrameMaker files into Confluence storage format. The syntax for links is documented here.

      You would then automate the addition of this content through the Confluence Remote API. A tool such as the Confluence Command Line Client could really help you here.

      1. I agree with Paul:

        the Confluence XML Export format is a tricky format to deal with. It's not really intended for human consumption.

        Also, as a user, I would tend to place more weight and value on advice from (an) Atlassian (specifically - and, I hope this does not make him blush, especially - Paul) than the scribbled notes of some random user experimenting in their spare time (me):

        You would then automate the addition of this content through the Confluence Remote API.

        Nevertheless, I've done some experimenting with XML export files on a local sandbox installation of Confluence 4.2. My aim is to get an understanding of the minimal markup required to import external content into Confluence (say, from FrameMaker) via an export file. Then I can use that understanding to automate the construction of export files, say, via XSLT, pulling body content from some other source (preferably, but not necessarily, already converted to Confluence storage format).

        First, I created three pages in my personal Confluence space: a parent page with two child pages. I added a link from one child page to the other. And I added an attachment to one of the child pages. Very simple.

        I selected the export option in Confluence (Browse > Confluence Admin > Administration > Backup and Restore), and then selected just those three pages for export (I also chose to export attachments).

        The resulting export .zip appeared to contain all of the contents of my personal space: certainly, many more pages than the three that I had selected, and a bunch of blog posts. Frustrating at the time, but in hindsight, probably valuable experience. I (very carefully) deleted all of the objects (from entities.xml) and attachments (from the attachments folder) except the ones I wanted, and then I made the following changes:

        1. Changed the following properties of the Space object: name, key, and spaceType (from "personal" to "global").
        2. Deleted all of the historicalVersions, outgoingLinks, ancestors, and labellings collections from the Page objects.
        3. Updated the .properties file to reflect the new Space key property value (I'm not sure, but I think these might have to match... this experiment raised a bunch of questions, but I'll save them for another comment).

        I think that's about all. The resulting trimmed entities.xml is 177 lines long. Reasonable for a minimal test case, I think (some page hierarchy, a link between pages, and an attachment).

        I rezipped the updated files, and imported the .zip. After re-indexing, I can view the imported (global) space and its three pages as expected.

        So far, I have seen only one error, which I get when browsing any of the three pages, which is one reason why I have not added the entities.xml (in an expand macro (wink) ) to this comment (I'd like to fix this error first):

        The root page @home could not be found in space Test import.

        I'll investigate: I have a reasonable inkling of what to do here, but if any Atlassian reads this and wants to help with specific advice, please feel free, I'd be grateful.

        [Fixed: I've added a homePage property to the Space object, referring to the "root" Page object; that is, the parent page of the other two pages.]

        I also plan to follow Paul's advice, and investigate using the API to add content ("directly"), rather than using export files. I hope that understanding the export file structure will give me a good head start on understanding the related parts of the API, because the contents of entities.xml are the persisted representations ("serialized forms") of the API objects. Understanding the API methods for working with those objects will definitely offer more flexibility than clicking the "Import" button, which constrains you to the pattern of API methods behind that button. On the other hand, if the "Import" button does what you want, and it turns out to be straightforward to roll your own export file...

      2. OK, I've set up MIF2Go to generate XHTML that Confluence 4.2 accepts as storage format. I've got all the paragraph and character tags working. Links are a little more challenging.

        For internal links, if I use the Remote API's storePage method, is it sufficient to make sure that all page names are unique? Is there a better place to discuss that?

        1. I'm not too sure what you are asking Robert. Internal links can be represented as shown in the body of the page -

          Space relative link
          <ac:link>
              <ri:page ri:content-title="Page Title" />
          </ac:link>

          'Page Title' should match the title of some page you have created (or are going to create) via the storePage API.

          If you need further answers you may find more help in Atlassian Answers.

    3. Hallo Robert

      I'm just wondering about this part of your question:

      The WebWorks tool is OK for publishing static pages but they're not editable.

      Is that a limitation of WebWorks ePublisher for Confluence 4 conversions? I've used ePublisher with Confluence 3.x, and it converts the FrameMaker content nicely to Confluence. The resulting Confluence pages are standard wiki pages, editable as usual.

      If you can get ePublisher to do the work for you, it may save quite a bit of time. It may even be worth experimenting with a two-stage conversion. Install a Confluence 3.5 wiki and push the pages from FrameMaker through ePublisher to Confluence, then upgrade the Confluence 3.5 site to Confluence 4.2?

      Cheers, Sarah

      1. My predecessors tried FrameMaker > WebWorks > Confluence 3.x a while back and had a similar experience, they said it looked fine but wasn't editable.

        Upgrading a whole 3.5 site to 4.2 doesn't sound workable in my situation. You can't migrate / convert one space at a time?

        1. Hallo Robert

          OK, I don't know about the problem with the pages not being editable. I'd like to know more – does it mean that WebWorks wraps the page content in some sort of HTML wrapper?

          If the above problem is cleared up, then there may be no need to go via Confluence 3.5 at all, provided WebWorks ePublisher supports Confluence 4.

          If WebWorks does not support Confluence 4, then this is how you could do it:

          • Download an evaluation version of Confluence 3.5.13 from here: http://www.atlassian.com/software/confluence/download-archives
          • Install it as a temporary site.
          • Push your FrameMaker content through WebWorks ePublisher into a new space on your temporary Confluence site. (Or a number of spaces, if that's what you need.)
          • Upgrade the temporary Confluence site to Confluence 4.2.
          • Refine the content, correcting any glitches that occurred during the migration and/or upgrade.
          • Export the space (or spaces) from your temporary Confluence site to Confluence XML. See the docs: Exporting Confluence Pages and Spaces to XML
          • Import the space or spaces from XML to your production Confluence site. (Note that the temporary site and the production site must be running the same 'major' version of Confluence. By major version, I mean that the first two numbers in the version number must be the same. I've assumed you'll be using Confluence 4.2.) See the documentation: Restoring a Space

          Cheers, Sarah

          1. Wow, that's quite a kludge, though I suppose I could create a VMware snapshot of the 3.5 Confluence instance and upgrade it repeatedly.

            The FrameMaker > WebWorks > Confluence 4.2 source was full of unnecessary macros and tables were broken up in a strange way.

            1. OK, here's what WebWorks creates in Confluence 3.5.13:

              {include:css.resource.css}

              {include:css.webworks.css}

              {table:cellspacing=0|summary=|style=margin-left: 0em; margin-right: auto;}
              {tr}
              {td}

              {td}

              {td}

              {td}

              {td}

              {td}

              {td}

              {td}

              {tr}

              {table}
              {div:class=WebWorks_Breadcrumbs}

              1 A Natural Source of Products : 1.2 North American Wetlands
              {div}

                      {anchor:146403}

                      North American Wetlands

              {anchor:140926}

              The symposium on Impact Assessment Study, was organized by the President’s Council on Environmental Quality (CEQ). It was hosted by the Ecological Society American Institute of Biological Sciences. The June 1976 event took place at historic Toluene University. Critical attention was directed at new trends in techniques and considerations that are methodological in their nature.
              {table:class=Activities|style=text-align: left; width: 495.4370400000001pt;|cellspacing=0|summary=}
              {tr}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 66.60648pt;}
              {anchor:146411}

              Activity
              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 246.66408pt;}
              {anchor:146413}

              Description
              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 90.72216pt;}
              {anchor:146415}

              Equipment
              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 91.44432pt;}
              {anchor:146417}

              Restrictions
              {td}

              {tr}

              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146422}

              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146424}

              Nothing compares to the pleasure of a brisk swim in Spirit Lake. Although fed by mountain streams, the lake is surprisingly comfortable in the summer.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146426}

              Towel service and massage year-round.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146428}

              Children under 14 are not allowed in the sauna, jacuzzi, or hot-tub.
              {td}

              {tr}

              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146435}

              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146437}

              For the mountain biker, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, riding either up or down the slopes.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146439}

              Rental bicycles available.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146441}

              Rt. 9 not recommended.
              {td}

              {tr}

              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146461}

              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146463}

              When the snow settles, our hiking trails are perfect for cross-country skiing. Members of our staff regularly mark the trails, and they comb them at the end of each day to make sure nobody is left out after dark.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146465}

              Rental skis and boots available.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146467}

              Children under 14 must be accompanied by an adult.
              {td}

              {tr}

              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146476}

              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146478}

              We have always been known for our Nordic ski slopes. We offer two lifts for intermediate to advanced skiers, and a tow rope for the beginning slope. If you are a guest for a week, all lifts are free of charge.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146480}

              Rental skis and boots available.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146482}

              Children under 9 are not allowed on the lifts.
              {td}

              {tr}

              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146489}

              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146491}

              Our hiking trails are known throughout the country. Plan a day trip or pack in for a week; it’s up to you. For a quieter setting, try paddling a canoe to the north end of Spirit Lake.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146493}

              Forestry Department maps for sale on premises.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146495}

              Please, don’t litter.
              {td}

              {tr}

              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146510}

              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146512}

              For the mountain runner, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, running either up or down the slopes.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146514}

              Top notch running shoes.
              {td}

              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146516}

              Stay on the running trails.
              {td}

              {tr}

              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146531}

              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146533}

              Members of our staff regularly play tennis at the nearby Wallaby Tennis center. The resident pro is Jerry Hubbard.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146535}

              Tennis rackets can be rotund at Jake’s.
              {td}

              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146537}

              Observe proper sign up times
              {td}

              {tr}

              {tr}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146539}

              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146541}

              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146543}

              {td}

              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146545}

              {td}

              {tr}

              {table}

              And here's what it looks like after upgrading to 4.2.2:

              <ac:macro ac:name="include"><ac:default-parameter>css.resource.css</ac:default-parameter></ac:macro>
              <ac:macro ac:name="include"><ac:default-parameter>css.webworks.css</ac:default-parameter></ac:macro>
              <ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{table:cellspacing=0|summary=|style=margin-left: 0em; margin-right: auto;}
              {tr}
              {td} [!images^toc.gif!|TableOfContents|Table of Contents] {td}{td} [!images^prev.gif!|1.02.Tropical Rain Forests|Previous] {td}{td} [!images^next.gif!|1.04.North American Deserts|Next] {td}{td} [!images^index.gif!|Index|Index] {td}
              {tr}
              {table}]]></ac:plain-text-body></ac:macro>
              
              <ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{div:class=WebWorks_Breadcrumbs}[1   A Natural Source of Products|1.01.A Natural Source of Products] : 1.2	North American Wetlands{div}]]></ac:plain-text-body></ac:macro>
              
              
              
              <hr />
              
              
              <ol>
              	
              <li>
              	
              <ol>
              		
              <li><ac:macro ac:name="anchor"><ac:default-parameter>146403</ac:default-parameter></ac:macro> <strong>North American Wetlands</strong></li>
              	</ol>
              	</li>
              </ol>
              
              
              
              <p><ac:macro ac:name="anchor"><ac:default-parameter>140926</ac:default-parameter></ac:macro> The symposium on Impact Assessment Study, was organized by the President&rsquo;s Council on Environmental Quality (CEQ). It was hosted by the Ecological Society American Institute of Biological Sciences. The&nbsp;June 1976 event took place at historic Toluene University. Critical attention was directed at new trends in techniques and considerations that are methodological in their nature. </p>
              
              <ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{table:class=Activities|style=text-align: left; width: 495.4370400000001pt;|cellspacing=0|summary=}
              {tr}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 66.60648pt;}
              {anchor:146411} *Activity*
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 246.66408pt;}
              {anchor:146413} *Description*
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 90.72216pt;}
              {anchor:146415} *Equipment*
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 91.44432pt;}
              {anchor:146417} *Restrictions*
              
              {td}
              {tr}
              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146422}  !1.03.North American Wetlands^resource.1.03.1.jpg|alt=,width=52,height=65,title=resource.1.03.1.jpg,! 
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146424} Nothing compares to the pleasure of a brisk swim in Spirit Lake. Although fed by mountain streams, the lake is surprisingly comfortable in the summer.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146426} Towel service and massage year\-round.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146428} Children under 14 are not allowed in the sauna, jacuzzi, or hot\-tub.
              
              {td}
              {tr}
              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146435}  !1.03.North American Wetlands^resource.1.03.2.jpg|alt=,width=89,height=64,title=resource.1.03.2.jpg,! 
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146437} For the mountain biker, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, riding either up or down the slopes.
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146439} Rental bicycles available.
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146441} Rt. 9 not recommended.
              
              {td}
              {tr}
              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146461}  !1.03.North American Wetlands^resource.1.03.3.jpg|alt=,width=64,height=67,title=resource.1.03.3.jpg,! 
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146463} When the snow settles, our hiking trails are perfect for cross\-country skiing. Members of our staff regularly mark the trails, and they comb them at the end of each day to make sure nobody is left out after dark. 
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146465} Rental skis and boots available.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146467} Children under 14 must be accompanied by an adult.
              
              {td}
              {tr}
              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146476}  !1.03.North American Wetlands^resource.1.03.4.jpg|alt=,width=50,height=50,title=resource.1.03.4.jpg,! 
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146478} We have always been known for our Nordic ski slopes. We offer two lifts for intermediate to advanced skiers, and a tow rope for the beginning slope. If you are a guest for a week, all lifts are free of charge. 
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146480} Rental skis and boots available.
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146482} Children under 9 are not allowed on the lifts.
              
              {td}
              {tr}
              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146489}  !1.03.North American Wetlands^resource.1.03.5.jpg|alt=,width=63,height=58,title=resource.1.03.5.jpg,! 
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146491} Our hiking trails are known throughout the country. Plan a day trip or pack in for a week; it’s up to you. For a quieter setting, try paddling a canoe to the north end of Spirit Lake.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146493} Forestry Department maps for sale on premises.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146495} Please, don’t litter. 
              
              {td}
              {tr}
              {tr}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146510}  !1.03.North American Wetlands^resource.1.03.6.jpg|alt=,width=57,height=55,title=resource.1.03.6.jpg,! 
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146512} For the mountain runner, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, running either up or down the slopes.
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146514} Top notch running shoes.
              
              {td}
              {td:style=background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146516} Stay on the running trails.
              
              {td}
              {tr}
              {tr}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146531}  !1.03.North American Wetlands^resource.1.03.7.jpg|alt=,width=57,height=60,title=resource.1.03.7.jpg,! 
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146533} Members of our staff regularly play tennis at the nearby Wallaby Tennis center. The resident pro is Jerry Hubbard.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146535} Tennis rackets can be rotund at Jake’s.
              
              {td}
              {td:style=border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;}
              {anchor:146537} Observe proper sign up times
              
              {td}
              {tr}
              {tr}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146539}  
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146541}  
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146543}  
              
              {td}
              {td:style=background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;}
              {anchor:146545}  
              
              {td}
              {tr}
              {table}]]></ac:plain-text-body></ac:macro>
              

               

               

          2. Sarah, these details on getting content out of FrameMaker and into Confluence (via WebWorks publisher) seem like something really useful to add to the main Confluence User's Guide somewhere. While Frame is not in my current workflow at all, I could easily see being 3 years down the road and thinking "I remember Sarah once had some really good steps for getting stuff out of Frame and into Confluence".

        2. I've pinged the WebWorks team to see if they can shed any light here.

          1. Here's a sample of some Confluence 4.2 source generated by WebWorks from the ecology.book sample project included with FrameMaker 10. This page has one short paragraph followed by a 4 x 8 table, total about 400 words.

            <p>
            <ac:macro ac:name="include">
            <ac:default-parameter>css.resource.css</ac:default-parameter>
            </ac:macro> <ac:macro ac:name="include">
            <ac:default-parameter>css.webworks.css</ac:default-parameter>
            </ac:macro>
            </p>
            <ac:macro ac:name="table">
            <ac:parameter ac:name="summary"/>
            <ac:parameter ac:name="style">margin-left: 0em; margin-right: auto;</ac:parameter>
            <ac:parameter ac:name="cellspacing">0</ac:parameter>
            <ac:rich-text-body>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:rich-text-body>
            <ac:link ac:tooltip="Table of Contents">
            <ri:page ri:content-title="TableOfContents"/>
            <ac:link-body>
            <ac:image>
            <ri:attachment ri:filename="toc.gif">
            <ri:page ri:content-title="images"/>
            </ri:attachment>
            </ac:image>
            </ac:link-body>
            </ac:link>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:rich-text-body>
            <ac:link ac:tooltip="Previous">
            <ri:page ri:content-title="1.02.Tropical Rain Forests"/>
            <ac:link-body>
            <ac:image>
            <ri:attachment ri:filename="prev.gif">
            <ri:page ri:content-title="images"/>
            </ri:attachment>
            </ac:image>
            </ac:link-body>
            </ac:link>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:rich-text-body>
            <ac:link ac:tooltip="Next">
            <ri:page ri:content-title="1.04.North American Deserts"/>
            <ac:link-body>
            <ac:image>
            <ri:attachment ri:filename="next.gif">
            <ri:page ri:content-title="images"/>
            </ri:attachment>
            </ac:image>
            </ac:link-body>
            </ac:link>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:rich-text-body>
            <ac:link ac:tooltip="Index">
            <ri:page ri:content-title="Index"/>
            <ac:link-body>
            <ac:image>
            <ri:attachment ri:filename="index.gif">
            <ri:page ri:content-title="images"/>
            </ri:attachment>
            </ac:image>
            </ac:link-body>
            </ac:link>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="div">
            <ac:parameter ac:name="class">WebWorks_Breadcrumbs</ac:parameter>
            <ac:rich-text-body>
            <ac:link>
            <ri:page ri:content-title="1.01.A Natural Source of Products"/>
            <ac:plain-text-link-body><![CDATA[1 A Natural Source of Products]]></ac:plain-text-link-body>
            </ac:link> : 1.2 North American Wetlands</ac:rich-text-body>
            </ac:macro>
            <hr/>
            <ol>
            <li>
            <ol>
            <li>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146403</ac:default-parameter>
            </ac:macro> <strong>North American Wetlands</strong>
            </li>
            </ol>
            </li>
            </ol>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>140926</ac:default-parameter>
            </ac:macro> The symposium on Impact Assessment Study, was organized by the President’s Council on Environmental Quality (CEQ). It was hosted by the Ecological Society American Institute of Biological Sciences. The June 1976 event took place at historic Toluene University. Critical attention was directed at new trends in techniques and considerations that are methodological in their nature.</p>
            <ac:macro ac:name="table">
            <ac:parameter ac:name="summary"/>
            <ac:parameter ac:name="style">text-align: left; width: 495.4370400000001pt;</ac:parameter>
            <ac:parameter ac:name="class">Activities</ac:parameter>
            <ac:parameter ac:name="cellspacing">0</ac:parameter>
            <ac:rich-text-body>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 66.60648pt;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146411</ac:default-parameter>
            </ac:macro> <strong>Activity</strong>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 246.66408pt;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146413</ac:default-parameter>
            </ac:macro> <strong>Description</strong>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 90.72216pt;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146415</ac:default-parameter>
            </ac:macro> <strong>Equipment</strong>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle; width: 91.44432pt;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146417</ac:default-parameter>
            </ac:macro> <strong>Restrictions</strong>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146422</ac:default-parameter>
            </ac:macro> <ac:image ac:height="65ac:title="resource.1.03.1.jpgac:width="52">
            <ri:attachment ri:filename="resource.1.03.1.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146424</ac:default-parameter>
            </ac:macro> Nothing compares to the pleasure of a brisk swim in Spirit Lake. Although fed by mountain streams, the lake is surprisingly comfortable in the summer.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146426</ac:default-parameter>
            </ac:macro> Towel service and massage year-round.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146428</ac:default-parameter>
            </ac:macro> Children under 14 are not allowed in the sauna, jacuzzi, or hot-tub.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146435</ac:default-parameter>
            </ac:macro> <ac:image ac:height="64ac:title="resource.1.03.2.jpgac:width="89">
            <ri:attachment ri:filename="resource.1.03.2.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146437</ac:default-parameter>
            </ac:macro> For the mountain biker, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, riding either up or down the slopes.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146439</ac:default-parameter>
            </ac:macro> Rental bicycles available.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146441</ac:default-parameter>
            </ac:macro> Rt. 9 not recommended.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146461</ac:default-parameter>
            </ac:macro> <ac:image ac:height="67ac:title="resource.1.03.3.jpgac:width="64">
            <ri:attachment ri:filename="resource.1.03.3.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146463</ac:default-parameter>
            </ac:macro> When the snow settles, our hiking trails are perfect for cross-country skiing. Members of our staff regularly mark the trails, and they comb them at the end of each day to make sure nobody is left out after dark.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146465</ac:default-parameter>
            </ac:macro> Rental skis and boots available.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146467</ac:default-parameter>
            </ac:macro> Children under 14 must be accompanied by an adult.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146476</ac:default-parameter>
            </ac:macro> <ac:image ac:height="50ac:title="resource.1.03.4.jpgac:width="50">
            <ri:attachment ri:filename="resource.1.03.4.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146478</ac:default-parameter>
            </ac:macro> We have always been known for our Nordic ski slopes. We offer two lifts for intermediate to advanced skiers, and a tow rope for the beginning slope. If you are a guest for a week, all lifts are free of charge.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146480</ac:default-parameter>
            </ac:macro> Rental skis and boots available.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146482</ac:default-parameter>
            </ac:macro> Children under 9 are not allowed on the lifts.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146489</ac:default-parameter>
            </ac:macro> <ac:image ac:height="58ac:title="resource.1.03.5.jpgac:width="63">
            <ri:attachment ri:filename="resource.1.03.5.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146491</ac:default-parameter>
            </ac:macro> Our hiking trails are known throughout the country. Plan a day trip or pack in for a week; it’s up to you. For a quieter setting, try paddling a canoe to the north end of Spirit Lake.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146493</ac:default-parameter>
            </ac:macro> Forestry Department maps for sale on premises.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146495</ac:default-parameter>
            </ac:macro> Please, don’t litter.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146510</ac:default-parameter>
            </ac:macro> <ac:image ac:height="55ac:title="resource.1.03.6.jpgac:width="57">
            <ri:attachment ri:filename="resource.1.03.6.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146512</ac:default-parameter>
            </ac:macro> For the mountain runner, we have a nearly level trail around Spirit Lake, as well as a trail leading up to the ski slopes. Once there, you can try your hand at grades of varying difficulty, running either up or down the slopes.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146514</ac:default-parameter>
            </ac:macro> Top notch running shoes.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #E6FFE6; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 1px; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146516</ac:default-parameter>
            </ac:macro> Stay on the running trails.</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146531</ac:default-parameter>
            </ac:macro> <ac:image ac:height="60ac:title="resource.1.03.7.jpgac:width="57">
            <ri:attachment ri:filename="resource.1.03.7.jpg"/>
            </ac:image>
            </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146533</ac:default-parameter>
            </ac:macro> Members of our staff regularly play tennis at the nearby Wallaby Tennis center. The resident pro is Jerry Hubbard.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146535</ac:default-parameter>
            </ac:macro> Tennis rackets can be rotund at Jake’s.</p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 1px; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: top;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146537</ac:default-parameter>
            </ac:macro> Observe proper sign up times</p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="tr">
            <ac:rich-text-body>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146539</ac:default-parameter>
            </ac:macro>  </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146541</ac:default-parameter>
            </ac:macro>  </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146543</ac:default-parameter>
            </ac:macro>  </p>
            </ac:rich-text-body>
            </ac:macro>
            <ac:macro ac:name="td">
            <ac:parameter ac:name="style">background-color: #FFB2B2; border-bottom-color: #000000; border-bottom-style: solid; border-bottom-width: 3.0pt; border-left-color: #000000; border-left-style: solid; border-left-width: 1px; border-right-color: #000000; border-right-style: solid; border-right-width: 1px; border-top-color: #000000; border-top-style: solid; border-top-width: 3.0pt; padding-bottom: 6pt; padding-left: 3pt; padding-right: 3pt; padding-top: 6pt; vertical-align: middle;</ac:parameter>
            <ac:rich-text-body>
            <p>
            <ac:macro ac:name="anchor">
            <ac:default-parameter>146545</ac:default-parameter>
            </ac:macro>  </p>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>
            </ac:rich-text-body>
            </ac:macro>

            1. Hallo Robert

              Yes, I see what you mean. I tried pasting the above code into the Confluence source editor. This is what the page looks like before I try to save it:

              When I try to save the page, I get errors. Of course, those may be because the above is just a snippet of XML.

              I can see some unexpected macros on the page. I wonder: Does ePublisher assume that you have a specific plugin installed, that supplies those macros?

              A request: Would you put the above code into an expand macro, to make the train of comments shorter. (smile)

              Cheers, Sarah

              1. Ah "expand." I was looking for something starting with "code."

                Here are WebWorks' requirements for Confluence: 

                http://docs.webworks.com/ePublisher/2010.4/Help/01.Welcome_to_ePublisher/5.23.Planning_and_Installing

              2. Anonymous

                Folks, you still must have the Adativist Content Formatting macros installed to use ePublisher's Confluence output.  We are generating 3.* wiki markup and deploying that to a Confluence 4.x server.  To address complex table needs, one must use the Adativist macros.  So, they have to be installed on the Confluence 4.* server.

                We try to be very clear on what ePublisher is doing here.  We are generating 3.* markup.  We enabled ePublisher's Confluence deployment client to push that markup to Confluence 4.* servers.  We did not enable the format to support Confluence 4's XHTML markup.

            2. The bleeding obvious (with apologies if it's already been mentioned, and I've missed it): for better compatibility with, and editability in, Confluence 4, instead of all of those <ac:macro ac:name="table"> et al elements, WebWorks could generate the corresponding "native" (not sure I like that term, now that I've used it) Confluence elements - elements that have the same name as XHTML elements, rather than ac:macro elements. That is, instead of generating this:

              <ac:macro ac:name="table">
                <ac:parameter ac:name="summary"/>
                <ac:parameter ac:name="style">margin-left: 0em; margin-right: auto;</ac:parameter>
                <ac:parameter ac:name="cellspacing">0</ac:parameter>

              generate this:

              <table summary="" style="margin-left: 0em; margin-right: auto;" cellspacing="0">
              

              Lotsa luck with any non-blank table summary attributes, though: you can't currently add or edit these in the Confluence (4.2) rich text editor. And if you add a summary attribute via the Source Editor plugin, it gets stripped.

              (As a stopgap - until WebWorks offers a fix/update - writing an XSLT stylesheet to convert those ac:macro elements into XHTML table markup would be straightforward.)

            3. I'm curious: how does WebWorks represent, for importing into Confluence, page hierarchy? (That is, parent/child page relationships?) And does WebWorks put the intended Confluence page title somewhere; for example, does WebWorks use the intended Confluence page title as the file name of its XML snippets? Or will you need to scrape the title (such as "North American Wetlands") from the contents of each XML snippet?

              And do you really want to import into Confluence, as "static" markup (as per your example XML snippet) at the top of each page, that table of navigation links (TOC/next/previous/index) and div containing the breadcrumb trail? Maybe you do: maybe you're using Confluence for publishing only, not for editing, and you don't intend to make any changes to the page hierarchy that would render those static links incorrect. Just thought I'd check.

               

              1. WebWorks gets the page tree hierarchy right, or close to right.

                It gets page titles right, except for adding some random-ish numbers.

                It gets the page tree node sort right, which Confluence's own Word import does not.

                The nav junk at the top of the imported pages is part of WebWorks' defaults (holdover from its .chm or .hlp roots). If I can get it working for my purposes I'll suppress that.

    4. In case it's of any use to help understand the XML export format (for the purposes of rolling your own), here's a "minimal" (171 lines) entities.xml containing just three pages (one parent with two child pages) that I have successfully imported ("restored"):

      • Export test main topic (Body content: "Hello world.") - the home page of the new Space after import ("restore")
        • Topic A (Body content: "This is the body content of topic A." - also has an attachment, default.gif.)
        • Topic B (Body content: "This is the body content of topic B. See Topic A.", where "Topic A" is a link.)
      <?xml version="1.0" encoding="UTF-8"?>
      <hibernate-generic datetime="2012-05-09 20:22:42">
          <object class="Space" package="com.atlassian.confluence.spaces">
              <id name="id">10616833</id>
              <property name="name"><![CDATA[Test import]]></property>
              <property name="key"><![CDATA[timp]]></property>
              <property name="description" class="SpaceDescription" package="com.atlassian.confluence.spaces">
                  <id name="id">10551348</id>
              </property>
              <property name="homePage" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020129</id>
              </property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2008-11-12 15:13:32.786</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2008-11-12 15:13:32.879</property>
              <property name="spaceType">global</property>
          </object>
          <object class="Page" package="com.atlassian.confluence.pages">
              <id name="id">22020133</id>
              <property name="parent" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020129</id>
              </property>
              <collection name="ancestors" class="java.util.List">
                  <element class="Page" package="com.atlassian.confluence.pages">
                      <id name="id">22020129</id>
                  </element>
              </collection>
              <property name="space" class="Space" package="com.atlassian.confluence.spaces">
                  <id name="id">10616833</id>
              </property>
              <property name="title"><![CDATA[Topic B]]></property>
              <collection name="bodyContents" class="java.util.Collection">
                  <element class="BodyContent" package="com.atlassian.confluence.core">
                      <id name="id">22052896</id>
                  </element>
              </collection>
              <property name="version">1</property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2012-05-09 20:13:30.302</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2012-05-09 20:14:32.240</property>
              <property name="versionComment"><![CDATA[]]></property>
              <property name="contentStatus"><![CDATA[current]]></property>
          </object>
          <object class="Page" package="com.atlassian.confluence.pages">
              <id name="id">22020131</id>
              <property name="parent" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020129</id>
              </property>
              <collection name="ancestors" class="java.util.List">
                  <element class="Page" package="com.atlassian.confluence.pages">
                      <id name="id">22020129</id>
                  </element>
              </collection>
              <property name="space" class="Space" package="com.atlassian.confluence.spaces">
                  <id name="id">10616833</id>
              </property>
              <property name="title"><![CDATA[Topic A]]></property>
              <collection name="bodyContents" class="java.util.Collection">
                  <element class="BodyContent" package="com.atlassian.confluence.core">
                      <id name="id">22052894</id>
                  </element>
              </collection>
              <property name="version">1</property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2012-05-09 20:12:40.754</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2012-05-09 20:14:49.115</property>
              <property name="versionComment"><![CDATA[]]></property>
              <property name="contentStatus"><![CDATA[current]]></property>
              <collection name="attachments" class="java.util.Collection">
                  <element class="Attachment" package="com.atlassian.confluence.pages">
                      <id name="id">22511617</id>
                  </element>
              </collection>
          </object>
          <object class="Page" package="com.atlassian.confluence.pages">
              <id name="id">22020129</id>
              <collection name="children" class="java.util.Collection">
                  <element class="Page" package="com.atlassian.confluence.pages">
                      <id name="id">22020131</id>
                  </element>
                  <element class="Page" package="com.atlassian.confluence.pages">
                      <id name="id">22020133</id>
                  </element>
              </collection>
              <property name="space" class="Space" package="com.atlassian.confluence.spaces">
                  <id name="id">10616833</id>
              </property>
              <property name="title"><![CDATA[Export test main topic]]></property>
              <collection name="bodyContents" class="java.util.Collection">
                  <element class="BodyContent" package="com.atlassian.confluence.core">
                      <id name="id">22052893</id>
                  </element>
              </collection>
              <property name="version">1</property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2012-05-09 20:12:14.864</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2012-05-09 20:12:14.864</property>
              <property name="versionComment"><![CDATA[]]></property>
              <property name="contentStatus"><![CDATA[current]]></property>
          </object>
          <object class="Attachment" package="com.atlassian.confluence.pages">
              <id name="id">22511617</id>
              <property name="fileName"><![CDATA[default.gif]]></property>
              <property name="contentType"><![CDATA[image/gif]]></property>
              <property name="content" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020131</id>
              </property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2012-05-09 20:16:52.475</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2012-05-09 20:16:52.475</property>
              <property name="fileSize">1761</property>
              <property name="comment"><![CDATA[Default user icon]]></property>
              <property name="attachmentVersion">1</property>
              <collection name="imageDetailsDTO" class="java.util.Set"/>
          </object>
          <object class="BodyContent" package="com.atlassian.confluence.core">
              <id name="id">22052896</id>
              <property name="body"><![CDATA[<p>This is the body content of topic B.</p><p>See <ac:link><ri:page ri:content-title="Topic A" /></ac:link>.</p>]]></property>
              <property name="content" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020133</id>
              </property>
              <property name="bodyType">2</property>
          </object>
          <object class="BodyContent" package="com.atlassian.confluence.core">
              <id name="id">22052893</id>
              <property name="body"><![CDATA[<p>Hello world.</p>]]></property>
              <property name="content" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020129</id>
              </property>
              <property name="bodyType">2</property>
          </object>
          <object class="SpaceDescription" package="com.atlassian.confluence.spaces">
              <id name="id">10551348</id>
              <property name="space" class="Space" package="com.atlassian.confluence.spaces">
                  <id name="id">10616833</id>
              </property>
              <property name="title"/>
              <collection name="bodyContents" class="java.util.Collection">
                  <element class="BodyContent" package="com.atlassian.confluence.core">
                      <id name="id">10715185</id>
                  </element>
              </collection>
              <property name="version">1</property>
              <property name="creatorName"><![CDATA[grahan01]]></property>
              <property name="creationDate">2008-11-12 15:13:32.786</property>
              <property name="lastModifierName"><![CDATA[grahan01]]></property>
              <property name="lastModificationDate">2008-11-12 15:13:32.786</property>
              <property name="versionComment"><![CDATA[]]></property>
              <property name="contentStatus"><![CDATA[current]]></property>
          </object>
          <object class="BodyContent" package="com.atlassian.confluence.core">
              <id name="id">22052894</id>
              <property name="body"><![CDATA[<p>This is the body content of topic A.</p>]]></property>
              <property name="content" class="Page" package="com.atlassian.confluence.pages">
                  <id name="id">22020131</id>
              </property>
              <property name="bodyType">2</property>
          </object>
          <object class="BodyContent" package="com.atlassian.confluence.core">
              <id name="id">10715185</id>
              <property name="body"><![CDATA[]]></property>
              <property name="content" class="SpaceDescription" package="com.atlassian.confluence.spaces"><id name="id">10551348</id>
              </property>
              <property name="bodyType">0</property>
          </object>
      </hibernate-generic>

      Notes:

      • The parent page refers to its children, and the children refer to their parent. I wonder if I could get away with removing one of these sets of pointers?
      • I also wonder what would happen if I didn't supply any of the following properties:

        version, creatorName, creationDate, lastModifierName, lastModificationDate, versionComment, contentStatus. Easy enough to populate these automatically, though, using an XSLT stylesheet (or some other programmatic method).

      • The newly imported/restored space doesn't automatically appear in the list of spaces on the dashboard (regardless of whether I select "re-index" for the restore). It seems I have to rebuild the site Search Index; then the new space appears. I wonder: is this entities.xml too minimal? Is it missing something that would somehow "trigger" the appearance of the new space, without requiring me to manually initiate a rebuild of the Search Index? Ah, I've just realized that I've specified a blank title property on the SpaceDescription object (although I have specified a name property on the Space object). Maybe that's it.

  52. I'm still working on converting from FrameMaker to Confluence 4.2 with the source showing up as proper storage format XHTML rather than some mashup including wiki markup and macros.

    I've got conversion working using MIF2Go to the point that each FrameMaker topic (topic breaks before H1, H2, and H3) is exported to an XHTML file that conforms to the Confluence 4.x storage format.

    I can paste that page by page into the Confluence 4.2 source editor, but with thousands of pages of documentation, that's not a solution, plus all the internal links need to be recreated.

    I can't figure out how to do a bulk import. Everything I've found that does that produces wiki markup. Is the Universal Wiki Converter being updated to produce 4.x storage format?

    1. Hi Robert. I don't know what OS you are on, but if you were on something Unix like (including Mac OS X) you might be best served by a short shell script and the Confluence Command Line Client.

      So assuming you have a single directory full of your XML files, an example script would be along the lines of -

      #!/bin/bash
      OLDIFS=$IFS
      IFS=$(echo -en "\n\b")
      for xmlfile in $(find . -name \*.xml)
      do
          ./confluence --action storePage --space "<YOUR SPACE>" --title "<TODO>" --file "$xmlfile"
      done
      IFS=$OLDIFS

      The above is untested and missing extraction of title (<TODO>). Hopefully someone who thinks Bash more than I do can fill in the blanks.

      1. Yes, we could script it. If we have to write our own tool I'm inclined to use the API, since the Command Line Client is unsupported.

      2. The Confluence Command Line Client does not seem to work as documented with 4.2. I can't specify parents, the page name doesn't match what I specify, and and I get two pages for each file.

  53. This sounds intriguing:

    Wednesday 4:45 pm - 5:30 pm

    Extending XML with SHORTREFs specified in RELAX NG

    Mario Blažević, Stilo International

    When SGML was replaced by its simplified successor XML, nobody regretted the omission of SHORTREFs. Or did they? Non-XML syntaxes stubbornly persist in programming languages, schema languages, and most visibly of all in wikis. We present a novel method for specifying a concrete syntax that combines the notational convenience of non-XML markup with the structure, searchability, and tool-chain support of XML, allowing authors to create valid XML without entering any XML tags. Using an extension of Relax NG to specify a concrete syntax, a parser can read a well-formed XML document conforming to the given concrete syntax specification. The output of the parser is another XML document conforming to the abstract syntax described by the base Relax NG schema.

    (Balisage 2012 Conference)

    A syntax with the convenience of wiki markup, but without XML round-tripping problems, because you're not really round-tripping? Sounds like a refreshingly technically rigorous new take on an old chestnut.

    I'd like to understand the constraints of such a "concrete syntax". If Confluence 3 wiki markup does not pass muster as is, perhaps a recognizable variant might? Would that change your mind about a wiki markup editor in Confluence?

    1. This is exactly what I advocated back in January when I first learned (to my dismay) about the loss of wiki markup syntax in 4.x. I think Atlassian could have simply evolved their native wiki syntax to more XML/HTML friendly, namely by introducing the concept of "end tags". For example, instead of {panel}content{panel}, you'd have {panel}content{/panel} or some such.

      This change alone would have made it possible (IMO) to solve their user-facing business goals regarding a better RTE editor that played nicely with wiki syntax as the storage format. (But not necessarily their architectural or coding overhead goals.)

      I think Atlassian forgot/overlooked an important distinction between HTML, XML, and wiki syntax. Just like XML is not a replacement for HTML, neither XML nor HTML is a replacement for wiki syntax:

      • XML was designed to transport and store data, with focus on what data is
      • HTML was designed to display data, with focus on how data looks
      • Wiki syntax (or more properly, a "markdown" syntax) was designed to make content authoring with basic, commonly-needed markup fast and simple. Everyone knows that directly authoring/parsing any SGML-based language is a royal PITA; that's exactly why the markdown syntaxes of various stripes have become so popular, and why many formerly happy Confluence users are indeed upset over this change. With the move to 4.x, we lost the fast and simple part of the equation. I know the dream of an RTE is that it should be faster and simpler than even a markdown syntax, but the reality is that bugs and other usability quirks can in fact make an RTE far less fast and simple to work with, compared to markdown syntax.
  54. Simple dumb question: how do I get the text in the storage format pop-up window to wrap? TIA.

     

  55. Anonymous

    Have a question: How can I get rid of anchor underlines in the macro for linking to other confluence pages. 

    1. Links to other Confluence pages are just normal HTML links. These can be customised via a custom stylesheet in a administration screen for a space (Space Admin > Look and Feel > Stylesheet).

      Note however that page links are treated like any other link (with nothing special to differentiate them), so removing the underline will affect all links. However, some types of other links can be differentiated (e.g. external links).

      For example, the following style will make all links within the pages content be displayed without an underline. The second rule adds underline back in to external links (which look like <a class="external-link" ...>link</a>).

      .wiki-content a, .wiki-content a:link, .wiki-content a:visited {
          text-decoration: none;
      }
      .wiki-content a.external-link, .wiki-content a.external-link:link, .wiki-content a.external-link:visited {
          text-decoration: underline;
      }

      An alternative rule is to filter via the "href" attribute (in this case I'm filtering on the href starting with a "/", i.e. a link to the same server - you may want to fine tune this to be more specific as it will apply to any link to the same server, not just pages).

      .wiki-content a[href^="/"], .wiki-content a[href^="/"]:link, .wiki-content a[href^="/"]:visited {
          text-decoration: none;
      }
  56. user-b12f0

    Please Can you make a DTD or an XSD schema for validating storage format available?