In the files I am importing I have text formatting attributes such as "align" in elements such as

or
. These are not being imported. This is because in the conversion to a DOMDocument all these attributes are converted to styles that are defined in the header. So the DOMDocument object now has two

elements. The first is the an original element from my document being imported. The second one is added by the call to the DOMDocument::loadxml() method in import_html's "parse_in_xml_file()" function. None of these two style elements make it past the example xsl file. This is because in the lines:
    <xsl:for-each select=".//head|.//xhtml:head">
      <xsl:for-each select="meta[@name]|xhtml:meta[@name]|rel|xhtml:rel|style|xhtml:style">
        <!-- copy most of the head - but NOT metas with http-equiv -->
        <xsl:copy><xsl:for-each select="@*"><xsl:copy></xsl:copy></xsl:for-each></xsl:copy>
      </xsl:for-each>
      <xsl:text>
      </xsl:text>
    </xsl:for-each>
the element is used instead of the element which would transfer the data part of the element containing the style class definitions. Because does not, what is transferred are two empty elements without any style data. But even if this file were tweaked to make the change to the styles will still not be imported because the function "import_html_xhtml_to_node()" imports only and elements from the header. So the import ends up with many class attributes in the body and no element in the header to define them. In my case, it happens that I do not want the element in the documents from the site I am importing because I prefer these styles be defined by the theme. But I do want to keep the element added by DOMDocument::loadxml() because I need attributes such as "align" to import. Right now all text I have center justified in the input document ends up being left justified in the import's output. My case will not be the same for everyone. There is a general need to be able to control what attributes and styles will be imported.

Comments

spflanze’s picture

Here is a better formatted version of my feature request:

In the files I am importing I have text formatting attributes such as "align" in elements such as <p> or <h1>. These are not being imported. This is because in the conversion to a DOMDocument all these attributes are converted to styles that are defined in the header. So the DOMDocument object now has two <style> elements. The first is the an original <style> element from my document being imported. The second one is added by the call to the DOMDocument::loadxml() method in import_html's "parse_in_xml_file()" function.

None of these two style elements make it past the example xsl file. This is because in the lines:

    <xsl:for-each select=".//head|.//xhtml:head">
      <xsl:for-each select="meta[@name]|xhtml:meta[@name]|rel|xhtml:rel|style|xhtml:style">
        <!-- copy most of the head - but NOT metas with http-equiv -->
        <xsl:copy><xsl:for-each select="@*"><xsl:copy></xsl:copy></xsl:for-each></xsl:copy>
      </xsl:for-each>
      <xsl:text>
      </xsl:text>
    </xsl:for-each>

the element <xsl:copy> is used instead of the <xsl:copy-of> element which would transfer the data part of the element containing the style class definitions. Because <xsl:copy> does not, what is transferred are two empty <style> elements without any style data. But even if this file were tweaked to make the change to <xsl:copy-of> the styles will still not be imported because the function "import_html_xhtml_to_node()" imports only <meta> and <link> elements from the header. So the import ends up with many class attributes in the body and no <style> element in the header to define them.

In my case, it happens that I do not want the <styles> element in the documents from the site I am importing because I prefer these styles be defined by the theme. But I do want to keep the <style> element added by DOMDocument::loadxml() because I need attributes such as "align" to import. Right now all text I have center justified in the input document ends up being left justified in the import's output.

My case will not be the same for everyone. There is a general need to be able to control what attributes and styles will be imported.

dman’s picture

Good assessment.
The meta-header importer came first (a singleton), then rel elements (also singletons), then style tags were added - *often* a singleton, but not if it has inline content.
Well, even if inline content was supported, most of the time we'd be expecting to discard it, so it's no big deal. It sounds like this is your case also.

It sounds like what is actually bugging you is that the inline styles migrated into the header. You want inline styles to stay where they were. Fair enough - (unless it was paste-from-word)

Well, that shifting of styles into the header will have been done by html tidy - NOT by the XML import step. You can find the options to tell HTML Tidy to do that - or not to do that - in coders_php_library/xhtml_tidy.conf - IF you are using the commandline version of tidy.

; clean: yes
; Using clean removes all inline css, even innocuous bits

If you are using one of the tidy extensions, the config is not that easy to find - it's in tidy-functions.inc. I never exposed a UI for it. My comments there indicate that this may not have always worked on all flavors of tidy. Or I wasn't doing it right.
turn on 'keep temp files' in the html tidy settings and see if you can send the right configs to your version of tidy.

spflanze’s picture

I have just discovered this on my own. Had I come back to this thread earlier to see your comment I could have saved myself three days. :) I actually wrote php code to move the styles from to the header back into the body.

There is no point to having clean enabled. Even if the example default XSL file is altered to retain styles, there does not appear to be a way to get the styles element into the Drupal node's header. So having Tidy move these attributes to the header means everything it moves there will be lost.

Besides the "clean" directive there is also "drop-font-tags" which should also be set to no.

dman’s picture

There is no CORE way to retain styles on a per-page basis, but there are a couple of extension modules that can support the idea of css-per-node. (I don't love any of them, but they are there).
The htmltidy 'clean' option is there to drastically remove all the inline styles put there by paste-from-word or FrontPage or random wysiwygs. There is a big point in that.
Most of the time, when importing legacy content to a new architecture and a new theme, it really is intentional to discard per-element inline styles. Many of those were accidental, or at least misguided.

You should have been using classes. If you need a class for 'align center' - add it and use it.
The import_html phase is (deliberately) taking the chance to relieve the old content of bad habits.

At least, that's the way I use it. Not to just 'maintain' legacy content, but to clean it up as we go. Having strip-font-tags in there is certainly deliberate.
... but enough of my philosophical views on that :-)

However - there is still the option for you to identify and deal with exceptions you wish to retain. The tidy options could be able to be exposed as a user choice. Because the import_html config screen doesn't have enough options already! I just never built a workable UI for it.

The XSL template (or a preprocessing phase) could possibly replace your <font style="size:big; color:red; font-face:Comic Sans MS"> with <span class="silly"> and the world would be a better place - And you'd have the effect you wanted.

spflanze’s picture

I lot of the content of the site I webmaster was generated by the founder of its political cause on MS Word. There are 1300 pages with these inline style attributes in them that I want to retain. This is too many for me to convert to a single CSS file that can be brought into the theme. I have finally tweaked import_html enough to get a good import. If you would like to see the static site which is still on the production server and the dynamic site with its migrated content on the testing server I will email you the links in private email.

It does not work to create a common CSS file from the styles Tidy migrates to the header because the class names Tidy creates are different for each page. For example on one page c2 might be text alignment and on another it might be a font color. The class association with an element tag is also not consistent. On one page it might div.c2 and on another it might be h1.c2.

Had the clean and drop-font-tags been exposed on the UI a lot of time would have been saved because I would have not have had to figure out why the inline styles were not being imported.

For this site it is not important for me to be able to control these styles from a single file in the theme. I just want the import to look like the static file.

dman’s picture

Version: 6.x-1.0 » 6.x-1.x-dev

I certainly understand your requirement to retain the dodgy inline styles. No need for a link - I can imagine.
Yeah, that could be an exposed option. But so could a few dozen more.
I agree that what html tidy does with shifting stuff into the header is not much use to anyone, It only does it per-page so there is no useful way to generalize it.

One idea was to allow you - with enough ability - to define your own htmltidy.conf. That's not exactly user-friendly, I know ... but is what I did when needed.
The alternative option - exposing a multitude of potential HTML tidy flags through the (already way-overloaded) UI is ... lots of work for small benefits I've not used yet.

My use-cases have always been to take the opportunity to clean up the legacy copy-paste crud. Where necessary, I isolate some common 'styles' during the XSL phase, but haven't done it a lot. Sometimes we need to farm off the 're-format process to a content editor and give them a restricted set of WYSIWYG classes.
But it's not my intent to remove choice either - if you need to keep the inlines - that's reasonable.
It's just a question of how much extra UI work would be needed to cover all cases. I think we should be able to at least tag these two flags. I still had issues with different versions of HTMLTidy, so it's flaky to ensure it would be possible to work on all platforms. Maybe.

dman’s picture

Status: Active » Postponed

The only way this can happen will be by exposing the htmltidy.conf for user management.
It's a lot of hassle to provide an inline editor for it (though do-able)
The thing I CAN see doing is allowing a user to choose and maintain their own htmltidy.conf in the files/ directory.

In the meantime - I strongly suggest that most users just edit the file
import_html/coders_php_library/htmltidy.conf directly to suit their taste. refer to the tidy manual for options. http://tidy.sourceforge.net/docs/quickref.html