Copy link to clipboard
Copied
Hi,
I have textbooks in which the order of the text needs to be rearranged. My idea: tag (?) textblocks with a number that will be the place where they go after rearranging and than sort by that tag.
So for instance:
in this textbook gets tag 4
with numbers gets tag 2
and addresses gets tag 3
a new order gets tag 1
after sorting by the tag will become
a new order
with numbers
and addresses
in this textbook
How can I do this?
Willy
Copy link to clipboard
Copied
There are various possibilities. One I can think of is this:
Add a character style to your document , call it e.g. tag, and set it to hide the text to which it is applied (0.1 point size, 1% hor. scale, paper colour). The add your tags to the beginning of your lines:
04in this textbook
02with numbers
03and addresses
01a new order
Then sort your lines using one of the available paragraph sortes. You can use SortParagraphs.jsx that comes with InDesign (which is a slow sorter) or you can use http://www.kahrel.plus.com/indesign/sort.html which is a bit quicker.
Peter
Copy link to clipboard
Copied
Hi Willy and Peter,
If the same context of 4 paras, this could be enough!
(^/)
Copy link to clipboard
Copied
Thank you Obi-Wan, I have a feeling it's near what I'm looking for. My textbook contains more than 250 textblocks to be rearranged, and I mean textblocks of one or more lines each. So this will be a bit more complicated I assume.
Willy
Copy link to clipboard
Copied
Show us screenshots! Thanks! 😉
(^/)
Copy link to clipboard
Copied
Hi,
A part of the file (exported as pdf) would be like this. Added in red is a number to represent the tag (?) or so which is the sequence to be. The number I use has a meaning: first two digits are for the chapter, Last 3 digits are for the paragraph in that chapter.
(Language is Dutch, sorry).
The result would look like this:
Thanks for your advice!
Willy
Op 23 feb. 2017, om 00:11 heeft Obi-wan Kenobi <forums_noreply@adobe.com> het volgende geschreven:
Sorting paragraphs by tagging (?)
created by Obi-wan Kenobi <https://forums.adobe.com/people/Obi-wan+Kenobi> in InDesign Scripting - View the full discussion <https://forums.adobe.com/message/9349671#9349671>
Show us screenshots! Thanks!
(^/)
If the reply above answers your question, please take a moment to mark this answer as correct by visiting: https://forums.adobe.com/message/9349671#9349671 and clicking ‘Correct’ below the answer
Replies to this message go to everyone subscribed to this thread, not directly to the person who posted the message. To post a reply, either reply to this email or visit the message page:
Please note that the Adobe Forums do not accept email attachments. If you want to embed an image in your message please visit the thread in the forum and click the camera icon: https://forums.adobe.com/message/9349671#9349671
To unsubscribe from this thread, please visit the message page at , click "Following" at the top right, & "Stop Following"
Start a new discussion in InDesign Scripting by email <mailto:discussions-community-indesign-indesign_scripting@adobe-v8.hosted.jivesoftware.com> or at Adobe Community <https://forums.adobe.com/choose-container.jspa?contentType=1&containerType=14&container=3331>
For more information about maintaining your forum email notifications please go to https://forums.adobe.com/thread/1516624 <https://forums.adobe.com/thread/1516624>.
This email was sent by Adobe Community because you are a registered user.
You may unsubscribe <https://forums.adobe.com/unsubscribe.jspa?email=info%40b-and-b.nl&token=edc26ad98845073a98ffd2d5aa29409baa9663c76106a1043b4c6fc6d49d303e> instantly from Adobe Community, or adjust email frequency in your email preferences <https://forums.adobe.com/user-preferences!input.jspa>
Copy link to clipboard
Copied
Hi Willy,
your last reply came without images.
To include images ( png or jpg ) log into the forum and do your reply with the forum controls.
You can attach images with "Insert Image":
You cannot attach images when replying by mail.
"Use advanced editor" functionality is not available when replying with InBox.
Regards,
Uwe
Copy link to clipboard
Copied
> would be like this:
> The result would look like this:
'This' didn't make it into your message.
P.
Copy link to clipboard
Copied
Before and after:
Copy link to clipboard
Copied
Hi Willy,
can you show a screenshot where hidden characters can be seen?
End of paragraph signs, end of line signs etc.pp.
Regards,
Uwe
Copy link to clipboard
Copied
I assume you mean this:
Willy
Copy link to clipboard
Copied
Hi Willy,
exactly.
I assume, that one block of text is from the start of a red number to the start of the next red number.
If not, you need not read the rest of this reply.
But you'd have a lot to explain.
Ok.
Since the text between two red numbers could be anything—paragraphs, lines, differently formatted text of variable length—I would work with a distinct color name for the numbers, that is absolutely unique to renumbering. If this should work by a script only the numbers, nothing else should be formatted this way.
And every single ordering number should be unique as well.
I would work with textStyleRanges and a selection of text.
Note: A textStyleRange is a uniquely formatted chunk of text.
All textStyleRanges in the text selection would be analyzed and the results of that process would be stored in an array structure.
The array would not store the formatted texts. Only some short strings and some numbers.
In detail:
1. Loop through the text style ranges of the selection and an array would be fed with items.
Every item of this array would be an array by itself and will contain:
A. The contents of the red text style range, the ordering number as a string
B. The index number of the text style range in relation to the selection
C. Added every index number of consecutive text style ranges until the next numbering text style range is found
If a new ordering number will be found a new entry goes to the array.
In essence the array a could be like this:
a = [ ["3",0,1,2,3] , ["1",4,5] , ["2",6,7,8,9,10,11] ]
Formatted number "3" starts the range of text styleRanges with index number 0, followed by three ranges, that are not formatted with the numbering color. Range index numbers 1, 2 and 3. Then formatted number "1" is found, followed by one additional range. Finally formatted number "2" is found followed by five additional text style ranges. I hope, you get the schema. The array is holding the information for three unordered blocks of text. The text style ranges indicate different formatting throughout a block of text. E.g. a word in bold or a different color, a paragraph that starts with a bullet etc, etc.
2. Then one could sort the array like that:
The sorting is done by the contents of our numbering strings from above, "3", "1" and "2".
a.sort(function(a,b){return a[0]-b[0]});
The result of sorting would be this:
a = [ ["1",4,5] , ["2",6,7,8,9,10,11] , ["3",0,1,2,3] ]
3. The sorted array would be looped
and all text style ranges that are indicated by their first and last index number would be duplicated as
textStyleRanges.itemByRange(startNumber,endNumber)
to a temporary text frame.
To stay in our little example:
for the first duplication action
the range is from: 4 to 5
the second action: 6 to 11
the third action: 0 to 3
4. Next: The unsorted text in the selection would be removed
5. Then the ordered text of the temporary frame would be moved to the first insertion point of the selection.
6. Finally the temp text frame would be removed.
Done. The text is re-sorted.
Regards,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
For me, the most important point is:
What is this 5-numbers numbering?
(^/)
Copy link to clipboard
Copied
https://forums.adobe.com/people/Obi-wan+Kenobi wrote
… For me, the most important point is:What is this 5-numbers numbering?
You have to ask Willy about the numbering scheme.
Not me.
It could be from 1 to n
Or it could be start from 1000 to n
Even 1.000 to n.nnn could do.
For the algorithm I presented it's not that important.
Important would be, that all numbers are unique.
And that they are formatted with one kind of formatting.
You could test the sort function for some schemas if you like.
But the best would be to use ordinary numbers in ascending order.
How and in what order the numbers are applied?
That's another question. And that's up to Willy.
Regards,
Uwe
Copy link to clipboard
Copied
Hi Obi-Wan,
The 5-digit number is representing the chapter and paragraphnumber within that chapter in which the paragraphs after sorting will have to be arranged. So, I know where the paragraphs have to land, but to copy/paste every paragraph seperately will lead to mistakes and take a lot of time.
There are different textstyles in the paragraphs, so if this messes everything up, as you said to Uwe, his idea's probably not suitable.
Again, I'll look in to it the coming weekend. Thanks for helping out!
Willy
Copy link to clipboard
Copied
willyw3761908 wrote
…
There are different textstyles in the paragraphs, so if this messes everything up, as you said to Uwe, his idea's probably not suitable.
Hi Willy,
"his ideas's" ? If you mean my idea, I have to say: My idea is working.
Maybe there are faster ways, but I think, my way is very flexible.
Look very hard into object textStyleRange
To quote DOM documentation:
"A continuous range of identical text formatting attributes."
Methods, properties that include duplicate() and move():
Adobe InDesign CS6 (8.0) Object Model JS: TextStyleRange
Adobe InDesign CS6 (8.0) Object Model JS: TextStyleRanges
Look into RegExp to extract numbers you can later sort:
returns Array textStyleRange.contents.match(/d+/)
Look into multidimensional arrays. And methods to sort them.
Select some text and test things like:
app.selection[0].textStyleRanges.everyItem().getElements()
app.selection[0].parentStory.textStyleRanges.everyItem().getElements()
Loop the result arrays.
Get information about values for properties like
contents and fillColor
As long as:
1. A single ordering number belongs to exactly one single textStyleRange
2. All ordering numbers share one property value—e.g. fillColor.name
3. That fill color name is used uniquely for ordering numbers
you have a hook to an ordering mechanism of formatted text from one ordering number to the next one. And it will not matter, how the text is formatted in between or how many paragraphs are in between two ordering numbers. Or if there are overrides of any kind in between…
Have a nice weekend,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
After having read a lot, Here's a new script version! …
The idea is simple: I use the "Grep-entities" sorting only to compare their "before/after places" in each story!
As the script "moves" the entities, no styling lost!
I've tested the script on 4 pages, one story [text frame] per page … That seems to work!
Thanks for comments!
Before script:
After script:
Script:
/*
Script written by Michel Allio [2017/02/26]
See: https://forums.adobe.com/message/9348834
Object: Sorting "Grep-Entities" paras!
*/
app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT, "Grep Sorting! …");
function main() {
var myDoc = app.activeDocument,
myStories = myDoc.stories.everyItem().getElements(),
S = myStories.length;
while(S--) {
//-----------------------------------------------------------------------------------------------------------------------------------
// Grep queries to define the "Text Entities"!
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = ".\\z";
app.changeGrepPreferences.changeTo = "$0\\r00000x";
myStories
.changeGrep();app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(?s)(^\\d{5}).+?(?=(?1))";
myFound = myStories
.findGrep();//-----------------------------------------------------------------------------------------------------------------------------------
var F = myFound.length;
// Temporary text frame per story!
var myGB = myStories
.characters[0].parentTextFrames[0].geometricBounds,myTempFrame = app.activeWindow.activePage.textFrames.add();
myTempFrame.geometricBounds = myGB;
// Sorting per story! In 2 steps:
// Step 1: the script "basically" sorts the entities but what a mess with the styles! So …
var myRandomArray = [];
for (var a = 0; a < myFound.length; a++) myRandomArray.push(myFound.contents);
var mySortedArray = myRandomArray.sort();
// Step 2: the script uses the sorting to compare each entity position in the 2 arrays:
// [in the "random" array [array of the "myFound" contents] AND [in the "sorted" array].
// When compared, the script moves each entity one per one in the right order in a temporary text frame [myTempFrame, per story]
for (var b = 0; b < mySortedArray.length; b++) {
var mySorted = mySortedArray;
for (var t = myFound.length-1; t >= 0; t--) {
if (mySorted == myFound
.contents) { myFound
.move(LocationOptions.before, myTempFrame.parentStory.insertionPoints[-1]); break;
}
}
}
// Last step:
myStories
.contents = "";myTempFrame.characters.itemByRange(0, myTempFrame.characters.length-2).move(LocationOptions.before, myStories
.insertionPoints[-1]);myTempFrame.remove();
}
app.findGrepPreferences = null;
}
(^/)
Copy link to clipboard
Copied
My God, this is like mathematics! Thanks Uwe, I just have to study on this this weekend! Come back to you thereafter.
Regards,
Willy
Copy link to clipboard
Copied
willyw3761908 wrote
My God, this is like mathematics! Thanks Uwe, I just have to study on this this weekend! Come back to you thereafter.
Hi Willy,
other algorithms could also be possible.
Obi-wan could do a clever GREP expression to store all text blocks as individual items in one array.
To sort that array would perhaps be a bit harder.
The text blocks could be duplicated from that array to different text frames. And the ordering numbers could be brought into relatonship to the unique IDs of their stories. Then you do an array of ordering numbers with their corresponding story ids and sort that. The last step would be to move the stories one by one—according to the sorted array—to the selection.
As Peter Kahrel said in reply 1, there are various possibilities.
Regards,
Uwe
Copy link to clipboard
Copied
Aha! Uwe, you're right! … I could do it!
Here's how I've imagined the game! … Maybe a little loony but it seems to work!
Thanks for comments!
I've supposed we play with stories and "Text entities" independent sorting into each of them!
I've used 2 para styles ["ParaStyle_1" in "Blue"; "ParaStyle_2" in "Black] but I've indicated how and where others could be added!
Before script:
After script:
Script:
app.doScript("main()", ScriptLanguage.javascript, undefined, UndoModes.ENTIRE_SCRIPT, "Sorting Text Entites Per Story! …");
function main()
{
var myDoc = app.activeDocument,
myStories = myDoc.stories.everyItem().getElements(),
S = myStories.length,
// myStyle_1
myStyle_1 = myDoc.paragraphStyles.item("ParaStyle_1"),
myStyleName_1 = "@1#",
// myStyle_2
myStyle_2 = myDoc.paragraphStyles.item("ParaStyle_2");
myStyleName_2 = "@2#";
// myStyle_n
//------------------------------------------------------------------------
while(S--) {
// myStyle_1
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = ".$";
app.findGrepPreferences.appliedParagraphStyle = myStyle_1;
app.changeGrepPreferences.changeTo = "$0" + myStyleName_1;
myStories
.changeGrep();// myStyle_2
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = ".$";
app.findGrepPreferences.appliedParagraphStyle = myStyle_2;
app.changeGrepPreferences.changeTo = "$0" + myStyleName_2;
myStories
.changeGrep();// myStyle_n
//-------------------------------------------------------------------------------
// Text Frame Last Para
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = ".\\z";
app.changeGrepPreferences.changeTo = "$0\\r00000x";
myStories
.changeGrep();
//------------------------------------------------------------------------------------------------------
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(?s)(^\\d{5}).+?(?=(?1))";
var myFound = myStories
.findGrep();var myArray = [];
for (var a = 0; a < myFound.length; a++) myArray.push (myFound.contents);
var myNewArray = myArray.sort();
for (var f = 0; f < myFound.length; f++) myFound
.contents = myNewArray ; //------------------------------------------------------------------------------------------------------
// myStyle_1
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(.)" + myStyleName_1;
app.changeGrepPreferences.changeTo = "$1";
app.changeGrepPreferences.appliedParagraphStyle = myStyle_1;
myStories
.changeGrep();// myStyle_2
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "(.)" + myStyleName_2;
app.changeGrepPreferences.changeTo = "$1";
app.changeGrepPreferences.appliedParagraphStyle = myStyle_2;
myStories
.changeGrep();// myStyle_n
//-------------------------------------------------------------------------------
// Text Frame Last Para
app.findGrepPreferences = app.changeGrepPreferences = null;
app.findGrepPreferences.findWhat = "\\r00000x";
app.changeGrepPreferences.changeTo = "";
myStories
.changeGrep();app.findGrepPreferences = app.changeGrepPreferences = null;
}
}
(^/)
Copy link to clipboard
Copied
Hi Obi-wan,
did not test your code.
Willy should see into it.
Hm. I think, you cannot assume that there are only two paragraph styles at play.
The text could be formatted with an arbitrary amount of styles.
Maybe there is only one with a lot of overrides?
That's the reason I suggest to work with textStyleRanges .
Regards,
Uwe
Copy link to clipboard
Copied
Hi Uwe,
My problem is with the "sorting"! It triggers a true mess with the styles!
The grep code to define the "entities" array works fine!
Maybe you could do something with it?
About the tags to be included at the end of each para, it could be automatically done playing with the para styles index through a loop!
About the overrides, i never make layout with a texts mess! I style them and only after I make the layout!
(^/).