Copy link to clipboard
Copied
is it possible to add group/folder with extendscript ?
Copy link to clipboard
Copied
Wow, that is a good question! I can't find anything in any documentation and I could not figure it out. I could insert a new file component with NewSeriesObject(), but could not convert it to a folder or group. It seems like ComponentType() is read-only. Maybe somebody else happens to know.
Russ
Copy link to clipboard
Copied
Should work like this:
var elemLoc = new ElementLoc() ;
elemLoc.parent = this.book.HighestLevelElement ;
elemLoc.offset = 0;
if (nextComponent.ObjectValid())
elemLoc.child = nextComponent.ComponentElement;
var newComponent = this.book.NewBookComponentOfTypeInHierarchy (folderName, Constants.FV_BK_FOLDER , elemLoc);
Same for groups.
Hope this helps
Markus
Copy link to clipboard
Copied
Well, I did see that, but I assumed the book was unstructured. I could not figure out how to do it without the structure-based methods. But now I play around with it a little more and I can't seem to even create an unstructured book (FM2015). So, are all books structured now?
Russ
Copy link to clipboard
Copied
Hi Russ,
I have to asked that question vice versa, have books ever been unstructured? 🙂
No I'm not sure. That's part of a script I wrote for a customer which uses FM12/FM2015 in an unstructured environment, and that was the only way I was able to solve that problem.
And I think customer also works with unstructured FM variant and he never complaint.
But I think Folders and Groups are features which came with FM9. And perhaps starting from then books have this "XML"-logic.
Markus
Copy link to clipboard
Copied
Thanks, what about adding .fm files to the group. ?
Copy link to clipboard
Copied
Hi,
var newComponent = null ;
if (unstructuredMode == false)
{
var elemLoc = new ElementLoc() ;
elemLoc.offset = Constants.FV_OBJ_END_OFFSET ;
elemLoc.parent = folderComponent.ComponentElement ;
newComponent = this.book.NewBookComponentInHierarchy (filename, elemLoc) ;
}
else
{
newComponent = this.book.NewSeriesBookComponent (folderComponent);
if (newComponent.ObjectValid())
newComponent.Name = filename;
}
Hope this helps
Markus
Copy link to clipboard
Copied
Hello,
I'm traying to create a .fm document into the folder using the solution of Wiedenmaier but my example doesn't work, All the time I have the error - 43, does anybody know where is the problem?
var book = app.ActiveBook;
var elemLoc = new ElementLoc (book.HighestLevelElement, null, 0);
var folder = this.book.NewBookComponentOfTypeInHierarchy ("Widget Guide", Constants.FV_BK_FOLDER, elemLoc);
var elemLoc2 = new ElementLoc() ;
elemLoc2.offset = Constants.FV_OBJ_END_OFFSET ;
elemLoc2.parent = folder.ComponentElement ;
var newComponent = this.book.NewBookComponentOfTypeInHierarchy(filename, elemLoc2) ;
Thanks in advance.
Copy link to clipboard
Copied
I had to create books with groups and folders years ago and I know it was not easy. In the end I made it work by calling the function to add a goup to the book via the Fcodes command:
Fcodes( [ FCodes['KBD_BOOKADDGROUP'] ] ); |
After this, the new group is the first (only) selected component in the book:
oNewComp = oBook.FirstSelectedComponentInBook; | |
oNewComp.BookComponentTitle = "My New Group Title"; |
Then you may also want to move the component up, down, left (promote) or right (demote):
oNewComp.MoveComponent( Constants.FA_COMPONENT_PROMOTE ); |
I hope this helps you enough to get it working.
4everJang
Copy link to clipboard
Copied
And doesn't exist any option to do this without Fcodes ?
Copy link to clipboard
Copied
I have not found one. But what is wrong with using Fcodes ?
Copy link to clipboard
Copied
4everJang schrieb
I have not found one. But what is wrong with using Fcodes ?
no control about anything 😉 Hate Fcodes 😉
Copy link to clipboard
Copied
That is not specific to Fcodes. Any built-in function does something that is largely out of control. Setting properties via SetProps( ) for instance often does all kinds of things that you can only guess at. I only use Fcodes when none of the other options works and I cannot afford to spend tons of time to figure out how to get around it. And for unstructured FM books, using the Fcode to add a group works fine - it does exactly what I would do when clicking the button for the command.
So I agree with you that having a proper Book method for inserting a group would be nice, but I cannot say I hate Fcodes, nor do I love them. They are just one of the tools in my toolbox.
Copy link to clipboard
Copied
I dug up some Code, and haven't tested it for this post. But I think this should help to understand the logic.
Please note this is only supported, if FM runs in structured mode. Didn't get it to work with unstructured mode (and I think i won't), but it shouldn't be a big issue to change this FM environment setting.
FMBookWrapper = function(book)
{
this.book = null ;
if (typeof(book) != 'undefined')
this.book = book;this.AddFolder = function(previousComponent, folderName)
{
var nextComponent = this.NextBookComponent (previousComponent, false);
var elemLoc = new ElementLoc() ;
elemLoc.parent = this.book.HighestLevelElement ;
elemLoc.offset = 0;
if (nextComponent.ObjectValid())
elemLoc.child = nextComponent.ComponentElement;
if (app.ProductIsStructured)
{
var newComponent = this.book.NewBookComponentOfTypeInHierarchy (folderName, Constants.FV_BK_FOLDER , elemLoc);
//needs to be done as book component is not valid at this point 😞
newComponent = this.FindBookComponent(newComponent);
}
else
{
alert("Not supported Error!\Adding folders is not supported with unstructured FM") ;
return ;
//TODO: this doesn't work... Function is not useable in unstructured FrameMaker
var newComponent = this.book.NewSeriesBookComponent (previousComponent);
if (newComponent.ObjectValid())
{
newComponent.ComponentType = Constants.FV_BK_FOLDER;
newComponent.BookComponentTitle = fileName.replace(".fm","");
}
}
//do some stuff with newComponent here
return newComponent;
}
this.NextBookComponent = function(bookComponent, dfsOrder)
{
if (typeof(dfsOrder)=='undefined')
dfsOrder = true ;
var comp=this.book.FirstComponentInBook;
if (bookComponent== null || typeof(bookComponent)=='undefined' || bookComponent.ObjectValid()==false)
return comp;
if (dfsOrder)
comp=bookComponent.NextBookComponentInDFSOrder;
else
comp = bookComponent.NextComponentInBook;
return comp ;
}
this.FindBookComponentByFileName = function(fileName)
{
var bookComponent = this.FirstBookComponent ();
while (bookComponent.ObjectValid())
{
if (bookComponent.Name == fileName)
return bookComponent;
bookComponent = this.NextBookComponent (bookComponent);
}
return bookComponent;
}
this.FirstBookComponent = function()
{
return this.book.FirstComponentInBook;
}
}
this functionality is wrapped in an object, you can use is like this.
var fmBook = new FMBookWrapper(app.ActiveBook);
var prevComp = null //get the component here. Folder is added after this book component
var folder = fmBook.AddFolder(prevComp, "MyFolder");//go ahead
Code creates a Folder. If you Need a Group, change FV_BK_Folder to FV_BK_Group in line 17. but this as a Parameter to AddFolder method, and both should work very smooth.
Hope this helps
Markus
Copy link to clipboard
Copied
Wiedenmaier,
I have problems with your example. The error is the next one: "this.FindBookComponent(newComponent); " is not a function.
Do you have any idea about this?
Thank you in advance!
Copy link to clipboard
Copied
Hi
sorry, assembled wrong function (FindBookComponentByFileName) instead of (FindBookComponent)
take this, which should do the job
FMBookWrapper = function(book)
{
this.book = null ;
if (typeof(book) != 'undefined')
this.book = book;this.AddFolder = function(previousComponent, folderName)
{
var nextComponent = this.NextBookComponent (previousComponent, false);
var elemLoc = new ElementLoc() ;
elemLoc.parent = this.book.HighestLevelElement ;
elemLoc.offset = 0;
if (nextComponent.ObjectValid())
elemLoc.child = nextComponent.ComponentElement;
if (app.ProductIsStructured)
{
var newComponent = this.book.NewBookComponentOfTypeInHierarchy (folderName, Constants.FV_BK_FOLDER , elemLoc);
//needs to be done as book component is not valid at this point 😞
newComponent = this.FindBookComponent(newComponent);
}
else
{
alert("Not supported Error!\Adding folders is not supported with unstructured FM") ;
return ;
//TODO: this doesn't work... Funktion is not useable in unstructured FrameMaker
var newComponent = this.book.NewSeriesBookComponent (previousComponent);
if (newComponent.ObjectValid())
{
newComponent.ComponentType = Constants.FV_BK_FOLDER;
newComponent.BookComponentTitle = fileName.replace(".fm","");
}
}
//do some stuff with newComponent here
return newComponent;
}
this.NextBookComponent = function(bookComponent, dfsOrder)
{
if (typeof(dfsOrder)=='undefined')
dfsOrder = true ;
var comp=this.book.FirstComponentInBook;
if (bookComponent== null || typeof(bookComponent)=='undefined' || bookComponent.ObjectValid()==false)
return comp;
if (dfsOrder)
comp=bookComponent.NextBookComponentInDFSOrder;
else
comp = bookComponent.NextComponentInBook;
return comp ;
}
this.FindBookComponent = function(bookComponent)
{
//Workaround implementation, because NewBookComponent, delivers component only with id and no other Props
if (bookComponent.ObjectValid()==false)
return bookComponent;
var comp=this.book.FirstComponentInBook;
while(comp.ObjectValid())
{
if (comp.ComponentElement.id == bookComponent.id)
return comp ;
comp=comp.NextBookComponentInDFSOrder;
}
return bookComponent ;
}
this.FirstBookComponent = function()
{
return this.book.FirstComponentInBook;
}
}//integrate
var fmBook = new FMBookWrapper(app.ActiveBook);var prevComp = null //get the component here. Folder is added after this book component
fmBook.AddFolder(prevComp, "MyFolder");
as mentioned, it's not tested in Detail.
But in an empty book, it creates a Folder and if you change "FV_Bk_FOLDER", to "FV_Bk_GROUP" it also creates a group in the book
Hope this helps
Markus
Copy link to clipboard
Copied
It create correctly the folder but how I can add ".fm" file into the folder?
Any idea about that?
Thanks!
Copy link to clipboard
Copied
When oLastComp points to the group or folder, this should work:
var oNewComp = oBook.NewSeriesBookComponent( oLastComp ); | |
oNewComp.ComponentType = Constants.FV_BK_FM; | |
oNewComp.Name = sFileName; |
Copy link to clipboard
Copied
Any idea to define the element parent? I don't know how I can say wich is the parent folder.
I can create a fm file document but not into the folder
var newComponent = this.book.NewBookComponentOfTypeInHierarchy (folderName, Constants.FV_BK_FOLDER , elemLoc); newComponent = this.FindBookComponent(newComponent);
var newElement = this.NextBookComponent (newComponent, false);
var elemLoc2 = new ElementLoc() ;
elemLoc2.parent =newElement ;
elemLoc2.offset = 0;
if (newElement.ObjectValid())
elemLoc2.child = newElement.ComponentElement;
var oNewCompBerria = this.book.NewSeriesBookComponent (newElement);
oNewCompBerria.ComponentType = Constants.FV_BK_FM;
oNewCompBerria.Name = "file.fm" ;
I can create this structure
book
-> folder
->file
-> folder 2
but I need something like this
book
->folder
->file
->folder 2
Copy link to clipboard
Copied
Hi,
add These lines after line 65
this.AddFileToFolder = function(folderComponent, filename, unstructuredMode)
{
if (typeof(unstructuredMode) == 'undefined')
unstructuredMode = !app.ProductIsStructured;
var newComponent = 0 ;
var elemLoc = new ElementLoc() ;
elemLoc.offset = Constants.FV_OBJ_END_OFFSET ;
elemLoc.parent = folderComponent.ComponentElement ;
var newComponent = null ;
if (unstructuredMode == false)
{
newComponent = this.book.NewBookComponentInHierarchy (filename, elemLoc) ;
}
else
{
newComponent = this.book.NewSeriesBookComponent (folderComponent);
if (newComponent.ObjectValid())
newComponent.Name = filename;
}
//search for component again. Sometimes you dont get the correct initialized bookcomponent back
newComponent = this.FindBookComponent(newComponent);
return newComponent;
}
and than you can call it like this:
var folder = fmBook.AddFolder(prevComp, "MyFolder");
fmBook.AddFileToFolder(Folder, "your filename");
should work
Markus
Copy link to clipboard
Copied
It works perfectly.
Thank you!
Copy link to clipboard
Copied
Hello,
I have other question about that, your code create the folders and files correctly but I have a litte problem with the order. I have created a loop to create differente folders and I wan't to know if exist any possibility to create the folders in different order, always you code create the last folder in the top of the list.
Your code:
Folder 2
File 2.1
File 2.2
Folder 1
File 1.1
I need :
Folder 1
File 1.1
Folder 2
File 2.1
File 2.2
Any idea about it?
Thank you!
Copy link to clipboard
Copied
I think you have to Change Line 11 in AddFolder from
elemLoc.offset = 0;
to
elemLoc.offset = Constants.FV_OBJ_END_OFFSET ;
this should insert Folder to the end of parent.
Please give it a try, and depending on Usecases you have to Play around with that.
Markus
Copy link to clipboard
Copied
Changing this line create this structure:
-My Folder 1
-Muy Folder 2
- File
But not folder 1 and 2 in the same level.
Copy link to clipboard
Copied
you need to Play around with the element Location, and I'm sure you'll find the solution 😉