Pages: 1
Print
Author Topic: Script Example: Custom Special Characters Form (XFT)  (Read 31678 times)
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« on: December 19, 2008, 08:08:01 PM »

Products: tested with XMetaL Author 5.1.1.017
(should probably work with any version of XMetaL that supports XFT, ie: 3.x and later)

Background:
There have been quite a few people lately asking for a feature that will let them easily add characters to the Special Characters and Symbols toolbars. Without going into great detail about why I would generally recommend against that, it basically comes down to the fact that in this case the main issue with extending toolbars is that they require an icon for each new button (to be understandable), which means in this case drawing a glyph for every character you want to let people insert (because the icons we ship are limited) and that would be a lot of work.

Instead, I've taken another project I'm working on and vastly simplified it to meet the needs of people that need a quick solution that might be good enough in a lot of cases.

It has been created so that even non-developers can take it and customize it meet their needs by placing the files in the right place and altering one plain text file using Notepad or another text editor to specify which characters they want to make available for insertion.

Installation:
Three files are attached in a zip file. Unzip and place them in the following locations (assumes you have a default installation of XMetaL Author 5.1 on an English language version of Windows XP):

C:\Program Files\XMetaL 5.1\Author\StartUp\xmetalExtension-customSpecialCharacters.mcr
C:\Program Files\XMetaL 5.1\Author\Forms\xmetalExtension-customSpecialCharacters.xft
C:\Program Files\XMetaL 5.1\Author\Forms\xmetalExtension-customSpecialCharactersConfig.txt

Then restart XMetaL Author to reload the MCR file.

Usage:
1. Run the macro called "Insert Custom Special Characters" to launch the form.
2. Click on a button to insert a (Greek) character.
3. (optional) Modify the first line in the TXT file so that the characters you want to appear in the form are used (instead of Greek).

The Files:
MCR: adds the macro called "Insert Custom Special Characters" to the Macros toolbar that launches the XFT form. If you don't like the name of this macro change it here. If you want to add a shortcut key for this macro do it here. If you want to add a toolbar button or menu item to run this macro the macro name specified in this file is the one you need to specify.
XFT: contains all the logic for rendering a bunch of buttons that display the characters you want to allow people to insert. This version allows a maximum of 128 characters (the reasons for this will be apparent if you are familiar with XFT and / or have access to the xflayout.exe tool and have a look at how it was done). I chose 128 characters because of the way I laid out the buttons (a grid of 16 columns x 8 rows). You could extend this, but I'm working on another solution that will probably be more flexible. If you need more characters today it might be fastest to simply duplicate this whole project change the filenames and launch two different XFT forms that call two different config files instead.
TXT:contains the characters you want to allow people to insert. This file is the only one most people will need to alter (assuming my XFT is not buggy and works OK for you).

Troubleshooting:
The controls in the XFT are all set to use "Arial" as the font. If you run into issues with certain characters not displaying properly that is a good place to check. You might need to modify the XFT for some character sets to use another font if you run into that type of problem (for which you will need XMetaL Developer and xflayout.exe). Make sure the TXT file is saved with Unicode encoding. It should not matter if the file contains a BOM as it is read in using Windows FSO and it should be able to handle with/without a BOM. The code in the XFT is written to assume Unicode encoding however.

I haven't tested this with control characters. In general people shouldn't be putting those in XML files anyway, so I don't see that as being a real limitation. I would probably avoid that. The XFT (and XMetaL Author itself) contains code to automatically handle the 5 special XML character entities (apos, quot, lt, gt, amp) so you can simply include them as the characters themselves (ie: "<" or ">") in the config file if you need them there (they're already on most keyboards so you probably would never do that).

* customSpecialCharactersV1.0.zip (9.6 KB - downloaded 642 times.)
« Last Edit: March 24, 2009, 03:28:23 PM by Derek Read » Logged
MarieS
Member

Posts: 9


« Reply #1 on: January 16, 2009, 08:33:49 PM »

How would I get this to actually write the hex code in the plain text view?
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #2 on: January 20, 2009, 07:58:24 PM »

How would I get this to actually write the hex code in the plain text view?

The example posted here inserts the character (not entity refs) into the XML source. I have posted some very possibly relevant information on the topic of encodings here as that question comes up from time to time: XML Document Encodings.

If you are saving to either ASCII or ISO-8859-1 and do require your documents to contain Unicode characters encoded as character entity references the scripts included with this example would not need to be modified because any characters contained in your document not supported by those encodings will be written out as hexadecimal character entity references (hopefully the other posting will clarify this for you).
Logged
LeoraBetesh
Member

Posts: 8


« Reply #3 on: March 05, 2009, 05:30:42 AM »

Hi Derek,

I have downloaded the macro and added the non-breaking hyphen to the txt file.   I used the macro to add the character to a file, and on output seems to work.

I have two questions about customizing the special character:
  • Can I change the symbol displayed for the character to something more recognizable as non-breaking hyphen?  If so how?
  • Can I change the appearance of the character in the normal view in XmetaL so it looks different from a regular hyphen?

Thanks,
Leora
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #4 on: March 05, 2009, 02:47:06 PM »

  • 1. Can I change the symbol displayed for the character to something more recognizable as non-breaking hyphen?  If so how?
  • 2. Can I change the appearance of the character in the normal view in XmetaL so it looks different from a regular hyphen?

Answers:
1. I did not design this example to work that way, but I suppose it could be modified to support a "display" character and a "character to insert". At the moment it uses the same for both.
2. The only way to do this in XMetaL Author at the moment (as of this writing the current release is 5.5) is to specify a font (in the CSS that is used by your DTD or Schema) that uses different glyphs for characters that otherwise look the same. Most fonts do not do this. In particular, for hyphen and non-breaking-hyphen, fonts do not do this precisely because people expect them to look the same.

One solution is to take an existing font file you normally use and modify it using a font editing application to change the particular characters you need to uniquely identify. Then use this new font in your customization when editing in XMetaL. I will not attempt to get into the legalities of modifying fonts. I suspect some might argue that even when not distributed externally this might contravene some licenses for some fonts. However, there are lots of open source fonts out there one could use / modify that would likely have less restrictions. Of course, this means having a font editing application and someone that knows how to use it. The necessary changes (in your case one character) would be very simple for people familiar with such software and might take about 10 minutes to perform.

I can say that long term we are looking into helping people solve this issue by adding features to XMetaL's UI. There are lots of characters in Unicode that tend to be rendered using the same glyphs in most fonts and people sometimes need to be able to identify them separately (there are a few dozen different "invisible" characters including U+0020 vs U+00A0, a bunch of characters that look like hyphens, sometimes with slightly different lengths, and lots of other lesser used characters).
Logged
LeoraBetesh
Member

Posts: 8


« Reply #5 on: March 24, 2009, 03:55:51 AM »

Hi Derek,
I would like the update the script to take every other character as the value to insert and the adjacent character as the display for the button.  (Or some other way to specify a display character so the writers can identify it.  It might also work to give a description of the character.)
I tried setting the buttons to take the even values in the array for display and to take the odd ones to insert but it didn't work.  The even values display but nothing is inserted.  I reduced the file to take 50 buttons instead of 128 for now.
I am attaching the xft file - let me add this is my first time using XMetaL developer so there may be some obvious mistakes there.
Thanks,
Leora

* InsertCustomChar.zip (6.76 KB - downloaded 548 times.)
Logged
mag3737
XMetaL Evangelist
Administrator
Member

Posts: 117

I even use XMetaL to write my business letters.


« Reply #6 on: March 24, 2009, 11:21:09 AM »

Hi Leora,

I find that using "interleaved arrays" often confuses me (and the code) when I'm writing script code.  I'm afraid I don't have time to try this out myself, but I would suggest using two arrays in the script (say "charArray" and "charInsertArray") and two corresponding lines of characters in the config file.  The first array/configtext will be used *only* for the characters to be shown on the buttons, and the second one is for the corresponding chars to be inserted into the document.

Changes to Derek's original script would be (hopefully I'm not missing something):

1. Add code to General Declarations section:
  a. Declare new array charInsertArray (defined outside all the functions so that it is globally visible to all objects in the form)
  b. Read second line of text from config file and construct the charInsertArray using the second line of text (the characters to be inserted into the doc)

2. Modify OnClick for every button XXX to typeChar(charInsertArray[XXX])

mag
Logged

Tom Magliery
JustSystems Canada, Inc.
LeoraBetesh
Member

Posts: 8


« Reply #7 on: March 24, 2009, 12:44:48 PM »

Thanks for the tip!  I will try it out.
Logged
mag3737
XMetaL Evangelist
Administrator
Member

Posts: 117

I even use XMetaL to write my business letters.


« Reply #8 on: March 24, 2009, 02:28:34 PM »

I did a partial test, and it looks like I was right.  I'm not posting my result because it would take way too long to go through and change all 128 of those OnClick() functions!

Three followup thoughts:

1. The button names (ButtonXXX) are 1-128, but the array index is 0-127, so the assignment in OnClick() is typeChar(charInsertArray[XXX-1])

2. Something probably should be done differently with the hoverChar() function. It should probably be displaying the "insert" character not the "display" character...depends on what you want, though.

3. This modification to Derek's original (which has a simple, narrow purpose) brings it a baby-step closer to being a general-purpose form with a series of arbitrarily-labelled buttons each of which inserts some arbitrary characters into your XML.  It's tempting to redesign the form from scratch with that in mind, but that's another thing I don't have enough time to play with today.
« Last Edit: March 24, 2009, 02:30:36 PM by mag3737 » Logged

Tom Magliery
JustSystems Canada, Inc.
LeoraBetesh
Member

Posts: 8


« Reply #9 on: March 31, 2009, 02:22:49 AM »

How do I declare the insert array to be a global variable so the form can view it as well?  Do I declare it in the script containing the setup function or elsewhere?
Logged
mag3737
XMetaL Evangelist
Administrator
Member

Posts: 117

I even use XMetaL to write my business letters.


« Reply #10 on: April 01, 2009, 02:15:56 AM »

Yes, declare the insert array in the same script with the setup function, but outside the function.

mag
Logged

Tom Magliery
JustSystems Canada, Inc.
jstaggart
Member

Posts: 11


« Reply #11 on: July 24, 2009, 11:44:58 AM »

I dowloaded these files and they seem to work with XMetal 5.5, but the Greek characters only output to html. They are blank in PDF output. Am I running into a font issue?
Logged
Su-Laine Yeo
Solutions Consultant
Member

Posts: 260


« Reply #12 on: July 24, 2009, 03:52:08 PM »

It could be. Details about font embedding in PDF are here: http://forums.xmetal.com/index.php/topic,366.0.html
Logged

Su-Laine Yeo
Solutions Consultant
JustSystems Canada, Inc.
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #13 on: July 25, 2009, 09:20:37 PM »

jstaggert, if you are producing output using XMetaL Author Enterprise using the DITA OT, or directly from the DITA OT (which you might have installed separately or integrated with another system) then that is most almost definitely your issue (99% sure). Revisiting that post Su-Laine has pointed to and getting a font embedded that contains glyphs for Greek characters will very likely be necessary.
« Last Edit: July 25, 2009, 09:31:55 PM by Derek Read » Logged
jstaggart
Member

Posts: 11


« Reply #14 on: July 27, 2009, 11:28:05 AM »

Is there any way around the 3 font limitation?
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #15 on: July 27, 2009, 11:58:21 AM »

There is no limitation that I'm aware of.

You might be thinking that because the DITA OT only uses 'Sans', 'Serif' and 'Monospaced' that there is a limitation, but that is not really the case. However, though you can define others, I don't believe that is really what you want to do here as these 'font alias names' (the XEP term) are used in almost every XSLT file used to generate the XSL-FO consumed by RenderX XEP.

I believe the simplest solution is to specify a font for each of the above that contains glyphs for Greek characters, such as "Arial" for 'Sans', "Times New Roman" for 'Serif' and "Courier New" for 'Monospaced'. I suggest these fonts because they are installed by default on every Windows XP and Vista machine and they contain the glyphs you need for Greek (open the font using the Windows Character Map tool to see all the characters / glyphs). The other post (http://forums.xmetal.com/index.php/topic,366.0.html) should get you there. One thing to note is that the file xep.xml already contains an entire section commented out that maps a bunch of fonts installed on standard Windows machines to their font files in the C:\Windows\Fonts folder (so that XEP can find them). They include "Arial", "Times New Roman" and "Courier New", so for that part you just need to uncomment that section in that file.

The alternative, more complex solution (which should not be necessary for Greek if you specify the fonts above) is to tell RenderX XEP to vary the font used by 'char-set'. That is done partially inside the font-mappings.xml file. The font-mappings.xml file that ships with the DITA OT includes settings for the following 'char-sets': "default", "Simplified Chinese", "Japanese", "Korean", "Symbols", "SubmenuSymbol", and "SymbolsSuperscript". The actual character sets that these names represent are defined in the file <DITA OT>\demo\fo\cfg\fo\i18n\en_US.xml (or the language file currently being used if xml:lang is not en_US and you have configured the DITA OT and your files to use xml:lang). So, if you need to further tweak this that is where the actual character sets are configured (ie: which sets of characters belong to "default", "Simplified Chinese", "Japanese", etc).
« Last Edit: July 27, 2009, 12:00:55 PM by Derek Read » Logged
jstaggart
Member

Posts: 11


« Reply #16 on: July 27, 2009, 01:03:16 PM »

My problem is I have already mapped sans, serif, and monospaced to Univers 45, Univers 57, and Univers 47. These fonts are our corporate standard. I tried pointing the charset for Greek to Arial, but this did not work. The Greek only outputs if I change either sans, serif, or monospaced to Arial. Am I out of luck with this?

Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #17 on: July 27, 2009, 04:15:09 PM »

In this case I believe you are going to be forced to the more advanced functionality I was referring to that use the "char-sets". Unfortunately I do not have any instructions handy for that and I'm not sure how quickly I can come up with something.

It would likely be most efficient to do this through our Professional Services team as I believe they have helped several clients configure the OT in a similar way for their specific needs. Sales can put you in contact if you want to do it that way.
Logged
Derek Read
Program Manager (XMetaL)
Administrator
Member

Posts: 2621



WWW
« Reply #18 on: July 27, 2009, 05:03:49 PM »

OK, a quick test shows that this isn't too hard to figure out.

With a default installation prior to DITA OT deployment you need to modify the following three files:

1.
C:\Program Files\Common Files\XMetaL Shared\RenderX\xep.xml

Uncomment the section that enables the Windows font mappings to the fonts "Arial", "Times New Roman", "Courier New", "Tahoma", "Verdana" and "Palatino". The line just before that section of the file has the following comment:
    <!-- Sample configuration for Windows TrueType fonts.  -->

2.
C:\Program Files\Common Files\XMetaL Shared\DITA_OT\demo\xmfo\cfg\fo\font-mappings.xml

Add a new 'physical font' section inside each of the 'logical font' sections in that file to specify that Greek characters should be treated specially. You can call the 'char-set' anything you like provided it matches the setting in the next file (below). Note: If you prefer to use other fonts (perhaps you have a fancy one that you like to use just for Greek) you would first need to add a new section telling XEP where that font is in the previous file (above).

Here are the new 'physical font' sections I've added to font-mappings.xml:
Code:
                <logical-font name="Sans">
                        ...leave existing settings...
                        <physical-font char-set="Greek">
                                <font-face>Arial</font-face>
                        </physical-font>
                </logical-font>

                <logical-font name="Serif">
                        ...leave existing settings...
                        <physical-font char-set="Greek">
                                <font-face>Times New Roman</font-face>
                        </physical-font>
                </logical-font>

                <logical-font name="Monospaced">
                        ...leave existing settings...
                        <physical-font char-set="Greek">
                                <font-face>Courier New</font-face>
                        </physical-font>
                </logical-font>

3.
C:\Program Files\Common Files\XMetaL Shared\DITA_OT\demo\xmfo\cfg\fo\i18n\en_US.xml (or the actual file being used if you are using xml:lang)

Add a new 'alphabet' section with a 'char-set' value that is the same as you used in the previous file above. Here's mine:

    <alphabet char-set="Greek">
        <character-set>
            <character-range>
                <start include="yes">&#x0370;</start>
                <end include="yes">&#x03E1;</end>
            </character-range>
        </character-set>
    </alphabet>

Note that these values represent the main section for Greek characters defined in Unicode 5. If you use other characters that should be in there you'll need to expand that section. The ja_JP.xml file is perhaps a better example to look at as it is more complex than the default en_US.xml file.
Logged
jstaggart
Member

Posts: 11


« Reply #19 on: July 28, 2009, 06:14:21 AM »

Thanks Dereck! That worked great. I was just missing the alphabet char-set entry.
Logged
Pages: 1
Print
Jump to: