General XMetaL Discussion
XMetaL Community Forum › General XMetaL Discussion › Count Macro
-
WillSergent February 5, 2009 at 3:20 pm
Count Macro
February 5, 2009 at 3:20 pmParticipants 7Replies 8Last Activity 13 years, 12 months agoI use XMetal to work in SGML. What I would like is a little macro I can hit that will do a count of all times that the '
' tag is in the active document. I was working in Jscript, which I'm completely new too and I'm quite clueless. Does anyone know how to write a macro like this. dcramer February 5, 2009 at 4:17 pm
Reply to: Count Macro
February 5, 2009 at 4:17 pmThis is probably an annoying suggestion, but here's what I do:
1. Have a macro and corresponding menu item that opens the current document in emacs.
2. In emacs do M-x occurRET (where is the string you want to search for. M means “meta” and is usually the Alt key on a windows keyboard. When you do that, emacs opens another buffer that says, e.g. “5 lines matching
in buffer foo.sgml” and then lists those lines. When you click on a line in the list, it takes you to that spot in the file in the other buffer. I really don't know how people who don't use emacs live without things like this (and there are many more).
David
mag3737 February 5, 2009 at 9:22 pm
Reply to: Count Macro
February 5, 2009 at 9:22 pmPaste this into your document (all three lines):
[code]
//XMetaL Script Language JScript:
var nodelist = ActiveDocument.getElementsByTagName(“coc”);
ActiveDocument.Host.Alert(nodelist.length);
[/code]The 2nd-3rd lines are the actual script, which you could put into a macro if you wish.
The first line is a little bit of XMetaL magic that allows you to run script code quickly by pasting it into the active document.
Derek Read February 5, 2009 at 10:22 pm
Reply to: Count Macro
February 5, 2009 at 10:22 pmMag3737 has given you the exact answer for your very specific issue.
But…just in case you need to take this a little further at some point, XMetaL Author and XMAX also have an API called getNodesByXPath() which lets you use an XPath expression to return a list of nodes like getElementsByTagName() does. It would not give you any additional benefits in your very specific case. However, if for example you needed to know how many
are contained within another specific element and only that other element (assuming it might also appear elsewhere) you could use getNodesByXPath() instead. Of course, you will need to understand XPath to be able to use this API.
So, given the following SGML (or XML)…
[code] [/code]
…the following script will return the value 5, which is the same result Mag3737's script will give:
[code]//XMetaL Script Language JScript:
var nodelist = ActiveDocument.getNodesByXPath(“//coc”);
ActiveDocument.Host.Alert(nodelist.length);[/code]…the following script will return the value 3 (only those
inside ):
[code]//XMetaL Script Language JScript:
var nodelist = ActiveDocument.getNodesByXPath(“//parent/coc”);
ActiveDocument.Host.Alert(nodelist.length);[/code]Also, keep in mind that both of these APIs are case-sensitive. For XML people that should be a no-brainer, but I could see some SGML people not catching that (depending on your SGML Declaration file settings).
WillSergent February 9, 2009 at 3:52 pm
Reply to: Count Macro
February 9, 2009 at 3:52 pmThat worked perfectly! Thanks everyone.
Now, one more question, what can I do to make it simply move to the next COC tag in the current open document?
mag3737 February 9, 2009 at 6:00 pm
Reply to: Count Macro
February 9, 2009 at 6:00 pm[code]
//XMetaL Script Language JScript:
Selection.MoveToElement(“coc”);
[/code]or if you want to go backwards:
[code]
//XMetaL Script Language JScript:
Selection.MoveToElement(“coc”, false);
[/code]or if you want the entire contents of the
to be automatically selected when you get there: [code]
//XMetaL Script Language JScript:
Selection.MoveToElement(“coc”);
Selection.SelectContainerContents();
[/code]WillSergent February 10, 2009 at 2:41 pm
Reply to: Count Macro
February 10, 2009 at 2:41 pmFor some reason, it doesn't seem to be working. I failed to mention that the COC tags are not actually containers. They're just used to label whats a change on our end.
I don't know if that makes a difference or not, but it doesn't even seem to be selecting the next COC tag.
Derek Read February 10, 2009 at 7:02 pm
Reply to: Count Macro
February 10, 2009 at 7:02 pmThe only thing I can think of is that perhaps you have not specified the element name using the right text casing. With no SGML declaration file XMetaL defaults to all capitals for element names, so your script must also assume all capitals. It is easy to check this by simply looking at the name of the element you are trying to find in TagsOn view. If it appears as
then you need to search for “coc”, if it appears as then search for “COC”, or you might have so search for “Coc”. I've tested this and it works for SGML for both regular and empty elements so that isn't the issue. In your case it might be as simple as using this instead:
//XMetaL Script Language JScript:
Selection.MoveToElement(“COC”);WillSergent February 10, 2009 at 8:45 pm
Reply to: Count Macro
February 10, 2009 at 8:45 pmAppreciate it. That worked perfectly. I'm still learning a lot about these application macros. Thanks to everyone who helped me out there!
-
AuthorPosts
- You must be logged in to reply to this topic.