Determining the relationship between Stories and Pages - adobe-indesign

A bit of background before I astart: I am by no means an InDesign expert, but I've been tasked with pulling some text information out of our company's InDesign files to do a bit of analytics. Each InDesign file that I'm working with has multiple pages, and each of those pages use Stories from the Master page (Forgive me if I'm using the wrong terminology, I'm working on a limited understanding of the InDesign object model). Using the default Export All Text script as a starting point, I was able to expand that functionality to dump out other useful information; such as the geometric bounds. I've posted some of the code below:
myFileName = "StoryID" + myID + myExtension;
myFilePath = myFolder + "/" + myFileName;
myFile = new File(myFilePath);
myFile.encoding='text';
myFile.open('w');
containers = myStory.textContainers;
if (containers[0].overridden) {
for (i = 0; i < myStory.words.length; i++) {
myFile.write(myStory.words[i].contents);
myFile.write(" ");
}
myFile.write("\n");
}
else {
myFile.write(myStory.contents + '\n');
}
var geometry = containers[0].geometricBounds
myFile.write("++" + containers[0].parent.name + '\n');
myFile.write("$$" + geometry[0] + "\t" + geometry[1] + "\t" + geometry[2] + "\t" + geometry[3] + "\n");
pageitems = myStory.allPageItems;
for (j = 0; j < pageitems.length; j++){
myFile.write("--" + pageitems[0]);
}
myFile.close();
The question I have is, how do I determine all the pages that a Story appears in? For example, I lets say I have 4 pages: {Master, Region 1, Region 2, Region 3}. Region 1 - 3 all inherit a Story block from Master. When I run this script I only get one instance of the Story block, the instance belonging to Master. However, I would be interested to know that the Story block in question belongs to all 4 pages. I've tried accessing the allPageItems property but I keep getting 0 results.
Any help would be appreciated. I'm working on InDesign CS 6 if that helps

When you're accessing allPageItems of the Story element, you're accessing all of the page items that are anchored within that story, which I don't think is what you want.
When you access the allPageItems property you get 0 results because your Story doesn't contain any textFrames. The Story element is contained by textContainers not textFrames. I know it's confusing!
If you want to determine whether a story is on a particular page, you can access the textContainers’ parentPage property.
A Story flows through multiple textContainers. For example:
link link
TextContainer --> TextContainer2 --> TextContainer3
|_____________________________________________________________________|
|
Story
A Story can also contain textFrames, rectangles, words, etc. For example:
Story
___________________________________|__________________________________
| |
Word --> Word2 --> TextFrame --> Word3 --> Word4 --> Word5

Related

AWS lambda function to speak number as digit in alexa

I have tried to use say-as interpret-as to make Alexa speak number in digits
Example - 9822 must not read in words instead '9,8,2,2'
One of the two ways I have tried is as follows:
this.emit(':tell',"Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ "<say-as interpret-as='digits'>" + clientno + "</say-as>",'backup');
The other one is this:
this.response.speak("Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ "<say-as interpret-as='digits'>" + clientno + "</say-as>");
Both are not working but working on a separate fresh function.
Actually your code SHOULD work.
Maybe you can try in test simulator and send us the code your script produces? Or the logs?
I've tried the following:
<speak>
1. The numbers are: <say-as interpret-as="digits">5498</say-as>.
2. The numbers are: <say-as interpret-as="spell-out">5498</say-as>.
3. The numbers are: <say-as interpret-as="characters">5498</say-as>.
4. The numbers are: <prosody rate="x-slow"><say-as interpret-as="digits">5498</say-as></prosody>.
5. The number is: 5498.
</speak>
Digits, Spell-out and Characters all have the effect you want.
If you want to Alexa to say it extra slow, use the prosody in #4.
Try using examples #2 or #3, maybe this works out?
Otherwise the example from Amod will work too.
You can split number into individual digits using sample function ( please test it for your possible inputs-its not tested for all input). You can search for similar function on stackoverflow
function getNumber(tablenumber) {
var number = (""+tablenumber).split("");
var arrayLength = number.length;
var tmp =" ";
for (var i = 0; i < arrayLength; i++) {
var tmp = tmp + myStringArray[i] + ", <break time=\"0.4s\"/> ";
}
return tmp;
}
In your main function... call this
var finalresult = getNumber(clientno);
this.emit(':tell',"Hi "+clientname+" your "+theIntentConfirmationStatus+" ticket is sent to "+ finalresult ,'backup');
Edited: Yep, nightflash's answer is great.
You could also break the numbers up yourself if you need other formatting, such as emphasizing particular digits, add pauses, etc. You would need to use your Lambda code to convert the numeric string to multiple digits separated by spaces and any other formatting you need.
Here's an example based on the answers in this post:
var inputNumber = 12354987;
var output = '';
var sNumber = inputNumber.toString();
for (var i = 0, len = sNumber.length; i < len; i += 1) {
// just adding spaces here, but could be SSML attributes, etc.
output = output + sNumber.charAt(i) + ' ';
}
console.log(output);
This code could be refactored and done many other ways, but I think this is about the easiest to understand.

Looping error, too many records added

Ive been trying to write Access VBA code to automate the addition of replicates for germination tests.
Basically I have a form where I enter the total number of Reps (NoofReps) and the number of seeds per rep (RepSize) (e.g. 50 seeds). For each record added I want it to automatically add a record for each rep and automatically calc the Rep Number (i.e if i have 4 reps then it should add 4 records, numbered 1-4 reps) as well as the RepSize (e.g 50).
I have been trying out various loops based on information from this forum and other but am still getting errors with the number of records that it generates. I have tried both the "Do while" and "Do Until" but get the same result below either way.
Could someone please let me know where I am going wrong?...If i want 2 reps then it adds 2, If i want 3 then its 246, and if i want 4 it adds >30,000!!!
For the purposes of trying to fix the code I have started to type the number of reps manually into the code in the iNoofReps so that I know the error is in the code and not from the form.
Private Sub CmdAddReps3_Click()
Dim iRepNo As Integer ' stores the current value in the series
'Open the table
Set db = CurrentDb()
Set rstGReps = db.OpenRecordset("tblGReplicates")
' Initialise the variables
iRepNo = 1
iNoofReps = 3 'iNoofReps = Me.txtNoofReps
' Add the records using a loop
rstGReps.movefirst
Do 'Until rstGReps("RepNo") = (iNoofReps + 1) ' always want to include at least 1 repNo
rstGReps.AddNew
rstGReps("GTestID") = Me.GTestID
rstGReps("RepNo") = iRepNo
rstGReps("NoofSeed") = Me.txtNoOfSeeds
' Calculate the next RepNo value in the loop
iRepNo = iRepNo + 1
rstGReps.Update
rstGReps.moveNext
Loop Until rstGReps("RepNo") = (iNoofReps) + 1 ' so that the loop includes the final repNo.
MsgBox "Finished Looping"
rstGReps.Close
Set rstGReps = Nothing
Set db = Nothing
End Sub
Any help would be appreciated!!!
Well, you're moving next here: rstGReps.moveNext, and then you're comparing rstGReps("RepNo") = (iNoofReps) + 1 after moving next, thus being on an empty record, thus always equating to false.
Loop Until iRepNo = (iNoofReps) + 1 should fix it, then you're no longer referring to the recordset, which has already been set to the next record by the time you're referring to it.
You could also fix it by just eliminating this line:
rstGReps.moveNext
Since rstGReps.AddNew already moves the recordset to a new blank record, moving it forward after adding the record doesn't make much sense. If you remove it, you might want to remove the + 1 in Loop Until rstGReps("RepNo") = (iNoofReps) + 1

How to copy slices in a image?

I want to make a copy of front image which contains several slice, like this:
image with several slices
I used imageclone function
image front, img
front.getfrontimage()
img=imageclone(front)
img.showimage()
But it only copy the first slices.
Have anyone know how to make a copy of this kind of image >"<
Thanks a lot~
The easiest way to duplicate the image (regardless how it is displayed) is via its "container" - ImageDocument. Here are the codes:
ImageDocument imgDoc = GetFrontImageDocument();
number DoDeepCopy = 1;
ImageDocument newDoc = imgDoc.ImageDocumentClone(DoDeepCopy);
newDoc.ImageDocumentShow();
If you need to manipulate individual slices then it is more complicated. Hope this helps.
In extension to the accepted (correct and best) answer, it's worthwhile knowing how to come from an "image" to its imageDocument. You do this like in this example:
ClearResults()
image frontImg := GetFrontImage()
imageDocument frontDoc = GetFrontImageDocument()
Result( "Grapped from application:" )
Result( "\n\t Image: " + frontImg.ImageGetLabel() + "\t ID = " + frontImg.ImageGetID() )
Result( "\n\t Doc : " + frontDoc.ImageDocumentGetName() + "\t ID = " + frontDoc.ImageDocumentGetID() )
imageDocument docFromImg = frontImg.ImageGetOrCreateImageDocument()
Result( "\n Taken from image:" )
Result( "\n\t Doc : " + frontDoc.ImageDocumentGetName() + "\t ID = " + docFromImg.ImageDocumentGetID() )
image imgFromDoc := frontDoc.ImageDocumentGetImage( 0 )
Result( "\n Taken from imageDocument:" )
Result( "\n\t Image: " + frontImg.ImageGetLabel() + "\t ID = " + imgFromDoc.ImageGetID() )
Note that an image does not necessarily have an imageDocument. The imageDocument is only created when the image is displayed or saved. That is why the command is called ...GetOrCreate.
Similarly, an imageDocument may contain multiple images (or none).
This is all a bit convoluted, and it appears confusing because many of the "correct" commands following the internal class hierarchy are wrapped by simplification commands for scripting convenience.
f.e. Saving an image using SaveSave() takes an image variable, but it really needs to save an imageDocument. So it implicitly gets/creates one. Otherwise, the user would need to script the correct, but more 'complicated' script.Instead of:
string path = "C:\\test.dm4"
image img := GetFrontImage()
img.SaveImage( path )
One would need:
string path = "C:\\test.dm4"
string handler = "Gatan Format"
image img := GetFrontImage()
imageDocument doc = img.ImageGetOrCreateImageDocument()
doc.ImageDocumentSaveToFile( handler, path )
Also note: While the route of using imageDocuments is the correct way, you should know that "linePlot displays" are really special. They are imageDisplay objects that may contain more than one image, whereas imageDocuments are objects which may contain more than one imageDisplay. I am pointing this out so that you know that you need to add new images to an imageDisplay to get more slices in an slice image. If you add them to an imageDocument, you will get multiple linePlot displays in a single file.
Depending on how "deep" you need to know all of this, I would recommend reading the documentation section on "image/imageDocument/imageDisplay/components" and testing things a bit. If questions remain, post them here on StackOverflow :c)

AS3 dynamic text algorithm

Afternoon,
I have an odd algorithm. I would like to populate a string of code dynamically based on some user entry.
I have a multi-dimensional array with data in it and a multi-line input text field.
What I want is for a user to be able to enter some text
example:
00
01 - 02 - 03
comments: 12
my code would identify the numbers an treat everything else as text.
Thus, if my array is data[x][#], the # will correspond to their entry.
I would get
algorithm_string = data[x][0] + "\n" + data[x][1] + " - " + data[x][2] + " - " + data[x][3] + "\n" + "comments: " + data[x][12]
So the algorithm would construct the above, and then I could run through the code.
for(var x:int = 0; x < data.length; x++){
some_object._display_text.text = algorithm_string;
}
Ok so I want to first say that relying on a user to put in the entry exactly the way you want is probably not a good idea. They WILL make mistakes and your code WILL eventually not work as expected. I would recommend using 5 inputs restricted to numeric input, and labeling each field with which number should go in it.
However, you can accomplish what you are trying to do above like this:
var parts:Array = myInput.text.split(" ");
for (var i:int=0; i<parts.length, i++){
if(!isNaN(parseInt(parts[i]))){
// you have a number here.
data[x].push(parts[i]);
} else {
//this was not a number so ignore it
}
}
Again let me state I think you should refactor how you get the numbers, but that code will grab the numbers out and put them in the 0,1,2,3,and 4 indexes of your data[x], but relies on the user perfectly inputting the text every time.
Good luck! (refactor) :)

find all non-repeating paths through a set of connected nodes/process diagram

I am trying to understand if its possible in any reasonable way to establish a set of non-repeating paths through a given process diagram.
here are some basic facts about the process diagrams i have:
they have one or more start points
they have one or more end points
all start points have one connector leading from them
all steps have at least one or more inbound connectors and one or more outbound
connectors
if there is more than one of the following each must be
named:
Start terminators
End Terminators
Connections leading from a step
I have access to all of the data I can imagine being required (finding all start points, getting all connections, names of connections etc).
I basically want to find as many unique paths through the process from start point to end point where you don't go round in a circle repeatedly. so you can go through the same step several times but you cannot repeat a complete circuit more than once in any given route through.
This seems like the type of thing people would have written papers about and have proofs for why it can or cannot be done, I just dont know the magic words I need to google that ;-) Sudo code or similar would be ideal (and amazing) but I am happy to do my own reading if someone can point me in the right direction.
ANY SEARCH TERMS SUGGESTIONS VERY WELCOME AND GREATLY APPRECIATED
Note I would be interested solutions that suggest lots of extra "silly" possibilities that have to be reviewed by a human afterwards - it would still be interesting to see what it generated.
An bit of an example to clarify things:
G<--2-E<--1-F-2--|
| | ^ |
| 1 | |
| | 2 |
\/ \/ | \/
start--->A--->B---->C-1->D---end
some routes through:
start,A,B,C:1,D,end
start,A,B,C:2,F:1,E:1,B,C:1,D,end
start,A,B,C:2,F:1,E:2,G,A,B,C:1,D,end
start,A,B,C:2,F:2,D,end
nice but what about a more interesting one:
start,A,B,C:2,F:1,E:2,G,A,B,C:2,F:1,B,C:2,F:2,D,end
I hit C three times and each time I choose option two and there is no repeating.
Extra points: I was thinking that I can mark some of the nodes with multiple outbound connectors as being consistent within any given execution of a process.. e.g. if there is a "write code" process that has a decision point "language" with two outbound connectors "c#" and "java" I could say that within any given execution of this process it will always be either c# or java - that will never change during the execution of the process. as opposed to something that may change like "are there bugs?" which on first pass through might have a yes, then on the second pass through (after some fix bugs steps ;-) might have the outcome no.
Do you know any terms or techniques relating to this type of extra analysis / processing / definition?
EDIT: I added a example solution implemented in JS as an ansewer based on #Ishtar's answer.
How about a depth first search? This would walk through all the possible paths. The only difficult part is ignoring paths that would lead to the same cycle again. If you're at a node, you check if you been there before (a cycle), and make sure the same sequence isn't in the path already.
For example
start,A,B,C:2,F:1,E:1,B,C:2,F:1,E:1,B
From here, we can only go to C. Looking back(the last 4 nodes), we find the cycle C:2,F:1,E:1,B. The cycle exists already, so we can't go to node c. Since we can't go anywhere else, this branch doesn't give a correct path.
Pseudocode:
allpaths(path,node)
cycle = path.substring(path.lastIndex(node)) + node
if path.contains(cycle)
return
path = path + node
if node.isEndNode
print path
return
for child in node.children
allpaths(path, child)
is this relevant? finding all the elementary circuits of a directed graph. even if it's not the algorithm you use, it may help with appropriate definitions and names.
a complete example in a web page of #Ishtars solution, the graph is the one from the question... It seems to work, not extensively tested it. Its a far simpler solution than I was expecting ;-)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function connection(name, endPoint) {
this.name = name;
this.endPoint = endPoint;
}
function node(name) {
this.name = name;
this.connections = [];
this.addConnection = function (conn) {
this.connections[this.connections.length] = conn;
}
}
function printPath(path) {
document.getElementById('output').innerHTML =
document.getElementById('output').innerHTML
+ path + '<br />';
}
function allPaths(path, node) {
if (node.name == "end") {
printPath(path + ',' + node.name);
return;
}
cycle = path.substring(path.lastIndexOf(node.name)) + ',' + node.name;
if (cycle.length > 1 && path.indexOf(cycle) > 0) {
return;
}
for (var i = 0; i < node.connections.length; i++) {
allPaths(path + ',' + node.name + ":" +
node.connections[i].name
,node.connections[i].endPoint);
}
}
var start = new node("start");
var a = new node("A");
var b = new node("B");
var c = new node("C");
var d = new node("D");
var e = new node("E");
var f = new node("F");
var g = new node("G");
var end = new node("end");
start.addConnection(new connection("1", a));
a.addConnection(new connection("1", b));
b.addConnection(new connection("1", c));
c.addConnection(new connection("1", d));
c.addConnection(new connection("2", f));
d.addConnection(new connection("1", end));
f.addConnection(new connection("1", e));
f.addConnection(new connection("2", d));
e.addConnection(new connection("1", b));
e.addConnection(new connection("2", g));
g.addConnection(new connection("1", a));
</script>
</head>
<body onload="javascript:allPaths('start', a)";>
<div id="output"></div>
</body>
</html>
and here is the output (just in case anyone can spot a mistake ;-):
start,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:1,E:1,B:1,C:1,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:1,E:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:1,E:2,G:1,A:1,B:1,C:2,F:2,D:1,end
start,A:1,B:1,C:2,F:2,D:1,end
Guess I didn't know about jsFiddle when I wrote this, here is a fiddle with the above code in it:
http://jsfiddle.net/6bWMp/1/

Resources