Texinfo, how to deal with impossible next / previous? - emacs

I'm trying to write documentation in Texinfo format (must be traditional to Emacs, I guess). And it is a nightmare... Anyway, I could get to the point, where the source gives me less error then when I started, but the errors are impossible to understand and thus fix.
All of the errors boil down to "bad" next / previous / up nodes. And they all happen in places, where there can be no "next", no "previous" and no "up" nodes. I.e. The last node in the list does not have a next node, similarly, the first can't have a previous, and the top-level can't have an "up". Node. These are the exact messages I'm getting:
./i-iterate/info/i-iterate.texi:385: Next field of node
`dot-product|join|distinct' not pointed to (perhaps incorrect
sectioning?).
./i-iterate/info/i-iterate.texi:392: This node (return)
has the bad Prev.
./i-iterate/info/i-iterate.texi:199: Next field of
node `initially' not pointed to (perhaps incorrect sectioning?).
./i-iterate/info/i-iterate.texi:120: This node (for) has the bad Prev.
./i-iterate/info/i-iterate.texi:29: Next field of node `Top' not
pointed to (perhaps incorrect sectioning?).
./i-iterate/info/i-iterate.texi:120: This node (for) has the bad Prev.
My texti file structure is as follows:
- Top
|- menu-0
| |- menu-2
|- menu-1
<list of nodes>
I.e. nodes mentioned in menu-2 should have their top node in menu-0, and Top is the top node for nodes in menu-0 and menu-1.
for node is the first node in the menu-0, return node is the first node in the menu-1, dot-product|join|distinct is the last node in menu-2, initially is the last node of the menu-0.
Top node can't have previous / next / up nodes... for obvious reasons.
As requested, the offending nodes:
#node for, with, , Top
#node return, collect, , Top
#node dot-product|join|distinct, , permutations, for
#node initially, , finally, Top
Some more info. I could actually "fix" it by specifying the return node as the next node of initially and initially as a previous node of return. But this is not the desired effect, because they two belong in different sets of nodes.
Also, this is how the entire menu looks like:
#menu
* for:: A multi-purpose driver for doing variety of things.
* with:: A driver for variable declaration.
* generate:: A general purpose generator driver.
* repeat:: A simple driver for performing iteration N number of itmes.
* finally:: A driver that runs when the iteration finishes normally.
* initially:: A driver that runs before any code in the iteration.
#end menu
#strong{Keywords}
#menu
* return:: Returns the control flow to the form outside the loop.
* collect:: Generates a list with the cells being the experssion given.
* hash:: Generates a hash-table with the provided keys and values.
* skip:: Skips the execution of the rest of the loop body.
* previous:: Gives the value of the variable from the previous iteration.
* next:: Gives the value of the variable from the next iteration.
* output:: Prints the variable to the dedicated stream.
* insert:: Generates a vector and inserts elements into it.
* minimize:: Finds the minimum value of the variable.
* maximize:: Finds the maximum value of the variable.
* count:: Counts the number ot times this expression was executed.
* sum:: Sums the values of this variable.
* multiply:: Multiplies the values of this variable.
* reduce:: General purpose accumulation handler.
#end menu
#node for, with, , Top
#chapter Multi-purpose driver
... description of what for node is ...
#strong{For continuations}
#menu
* in|on:: Iterates over lists.
* upfrom|from|downfrom:: Iterates numberically.
* across|reverse|binary:: Iterates over arrays.
* depth-first|breadth-first:: Iterates over trees.
* keys|values|pairs:: Iterates over hash-tables.
* random:: Produces unique random each iteration.
* chars|words|lines:: Iterates over entities in buffer.
* permutations:: Generates permutation of an array.
* dot-product|join|distinct:: Iterates over sets.
#end menu

Just use #node for and #node return without the extra arguments. Texinfo will then automatically figure out the prev/next/up links based on #chapter and other sectioning commands.

Related

How to prevent cy.get from "snapshotting" a list before it's sorted

Not the best title, but here's my challenge. I have a list on my page that can be sorted, and I want a Cypress test that checks that it works as expected. So imagine this test:
/* 1 */ cy.get('.list-item').eq(0).should('have.text', 'A');
/* 2 */ cy.get('.list-item').eq(-1).should('have.text', 'Z');
// Code that triggers sorting to change from asc to desc
/* 3 */ cy.get('.list-item').eq(0).should('have.text', 'Z');
/* 4 */ cy.get('.list-item').eq(-1).should('have.text', 'A');
Looks simple, but there's a slight delay when the sorting happens, so the UI isn't updated immediately.
I'm not sure if it's the cy.get or the eq function which causes it, but the problem is that line 3 "captures" the first element in the list, which is still 'A', and then tries to assert that the text is 'Z'. And when the list is reordered, this "captured" element doesn't actually change, it's just moved in the DOM, so the assertion still tries to assert that same element 'A', which in the DOM is actually the last element now, is 'Z', which it obviously isn't and shouldn't be.
If I insert a cy.wait(100) before 3, then it works as expected, but obviously I do not want to have a random wait in my test, so how do I solve this?
How do I check what the first and last elements are in a situation like this, when Cypress captures the DOM elements before they're reordered, without inserting an arbitrary wait? 😕
Actual case
Support app, showing a list of the 5 most recently viewed clients
Need to test that, when visiting for example number 3 in that list, it is moved to the top
The "code that triggers sorting" is actually a route navigation event:
There's a listener (React useEffect hook) on route changes.
When route changes, it updates the list of recently viewed client ids, which is stored in local storage.
When the list in local storage changes, the component showing the list first waits 750ms (so it's less confusing for user, but turned down to 10ms in Cypress tests), then updates (re-sorts) the list.
And since the list only contains ids, each tile will then async load the name and some more stuff to display on the list item.
So... the delay is actually more than just a UI update. There's routing, local storage and async requests involved too. 🎉
You need to merge cy.get(...) and .eq into a single selector to make sure it retries the assertion .should('have.text', 'Z') after resorting. Read about it https://on.cypress.io/retry-ability#Merging-queries - right now it grabs the list and then only retries .eq() command, which is too late. You could also rewrite your code to get the first and last elements using single .should(cb) https://on.cypress.io/should#Function - the example in the docs really fits your use case.
I am taking a wild shot here, but perhaps in the trigger to sort you could use then.
cy.get('.list-item').eq(0).should('have.text', 'A');
cy.get('.list-item').eq(-1).should('have.text', 'Z');
// Code that triggers sorting to change from asc to desc
cy.get("#id-to-sort").click().then(()=>{
cy.get('.list-item').eq(0).should('have.text', 'Z');
cy.get('.list-item').eq(-1).should('have.text', 'A');
})

Two-sided references in a list

I'm just starting to learn Perl and I have to do an exercise containing references.
I have to create a program, that constructs a list with two sided references, that are are received as command line arguments. At the beginning of the program, there is only one element in the list - 0. To go through the list, reference is being used, that references to the only element of the list at the moment - 0. The arguments of the command line are being read one by one and added right behind the element, that is being referenced to. When one argument is added, the reference slides one element to the right(it references to the newly added element). There are also two special elements - + and -. + allows the reference to move one element to the right, and - one element to the left. Also, it is important that the reference would not go beyond the list limit.
The output is all the arguments in the correct order of the list.
Additional requirements are that the list must be created by using hashes, that contain links to neighbouring elements. Also, I cannot use arrays to store the whole list.
There are a few examples to make it easier to grasp the concept, this is the most useful one:
./3.pl A D - B C + E
0 A B C D E
All I've got now is just the start of the program, it is nowhere near done and doesn't compile, but I can't figure out where to go from there. I've tried looking for some information about two-sided references(I'm not sure if I'm translating it correctly), but I can't seem to find anything. Any information about two-sided references or any tips how to start writing this program properly would be very appreciated.
My code:
#!/usr/bin/perl
use strict;
use warnings;
my $A= {
value=>'0',
prev=>'undef',
next=>'$B'
};
my $B= {
value=>'0',
prev=>'$A',
next=>'$C'
};
my $C= {
value=>'0',
prev=>'$B',
next=>'undef'
};
for my $smbl(0..#$ARGV) {
$A-> {value} = $ARGV[$smbl];
$Α-> {next} = $ARGV[$smbl+1];
}
First of all, what you are building is called a doubly linked list.
Let me tell you the biggest trick for working with linked lists: Create a dummy "head" node and a dummy "tail" node. You won't print their values, but having them will greatly reduce the number of special cases in your code, making it so much simpler!
At the core, you will have three "pointers" (references).
$head points to the first node of the list.
$tail points to the last node of the list.
$cursor initially points to the node in $tail. New nodes will be inserted before this node.
When processing +, two different situations you need to handle:
$cursor == $tail: Error! Cursor moved beyond end of list.
$cursor != $tail: Point $cursor to the node following the one it references.
When processing -, there are two different situations you need to handle:
$cursor->{prev} == $head: Error! Cursor moved beyond start of list.
$cursor->{prev} != $head: Point $cursor to the node preceding the one it references.
When processing inserting nodes, no checks need to be performed because of the dummy nodes!

Matlab structure with Children that are arrays of structs, etc. - How do trace path to all children individually?

I have a Matlab structure, A, that has 3 fields. The first field is SignalName and the third field is Children. Children can either be empty or a Struct array with the same fields, and so on, to an arbitrary depth not immediately known to the user. SignalName is a character array which is the name of a signal.
I have written a recursive function (in Matlab) to retrieve all of the SignalName values for structures that have no Children, and it's pretty slick (I think), but I need to know the absolute path taken to arrive at said SignalName. I cannot figure this out in Matlab.
As an example:
A.SignalName = 'Things'
A.Children = <22x1 struct>
A.Children(1).SignalName = 'Places'
A.Children(1).Children = [8x1 struct]
This goes on for an unknown depth, and the length of the struct arrays is not immediately known. It is easy via recursion to 'dive' down and get all of the SignalNames belonging to Children with no further Children, but how do I trace the route I used to get there? My function would ideally return results as a signal name, and the path taken to said signal.
In my experience with other languages, it seems like something like A* or Breadth-First might help, but I'm not exactly searching for something. I want simply to map every node and the path to it, and I'm not sure how to do that with the strange data-structure I'm given.
Thanks for any help you all can provide!
EDIT: I wanted to provide the code to hopefully shed light on my issue. I can get the paths down to the deepest node, but any other nodes at that level leave me without a complete path to that specific location. This is what I need help with. I am using '*' as my delimiter for a regexp in my post-processing script to break up the strings in PATHS.
For two nodes at the same depth, I might get a full path like 'A.B.C.D.Signal1' for the first node, but the second would give me a path of 'D.Signal2', when what I need is 'A.B.C.D.Signal2'. If the path was the same to the 'D' level with every signal, I would just copy the path over, but I have multiple branches in this struct from each level, and I go 4 or 5 levels deep.
function [NAMES,PATHS]=FindSignals(A,TMP,TMP2)
persistent SigName;
persistent path;
SigName = TMP;
path = TMP2;
if(~isempty(A.Children)) % If this struct has Children
for i = 1:length(A.Children) % Iterate through the Children
nextStruct = A.Children(i);
path = strcat([path '*' A.SignalName]);
[NAMES,PATHS] = FindSignals(nextStruct,SigName,path); % Recurse
end
else % If this struct has no Children
path = strcat([path '*' A.SignalName '*']); % Finish the path to Child
SigName = char(SigName,A.SignalName); % Grab the signal name
NAMES = SigName;
PATHS = path;
end
end
Again, thanks for any help!
EDIT: 12/14/2015 - I'm still completely stuck on this. Could anyone please take a peek at my source code above? I am unsure how to tack on an absolute path to the recursive function call and allow it to be a full path for each node at the same depth, and then reset to the appropriate depth once I move up or down the 'tree'. Thanks.

Traversing DOM nodes in CKEditor-4

We have a bug at this CKEditor plugin, and a generic solution is like to this, applying a generic string-filter only to terminal text nodes of the DOM.
QUESTION: how (need code example) to traverse a selection node (editor.getSelection()) by CKEditor-4 tools, like CKEDITOR.dom.range?
First step will be to get ranges from current selection. To do this just call:
var ranges = editor.getSelection().getRanges();
This gives you an array of ranges, because theoretically (and this theory is proved only by Firefox) one selection can contain many ranges. But in 99% of real world cases you can just handle the first one and ignore other. So you've got range.
Now, the easiest way to iterate over each node in this range is to use CKEDITOR.dom.walker. Use it for example this way:
var walker = new CKEDITOR.dom.walker( range ),
node;
while ( ( node = walker.next() ) ) {
// Log values of every text node in range.
console.log( node.type == CKEDITOR.NODE_TEXT && node.getText() );
}
However, there's a problem with text nodes at the range's boundaries. Consider following range:
<p>[foo<i>bar</i>bo]m</p>
This will log: foo, bar, and bom. Yes - entire bom, because it is a single node and walker does not modify DOM (there's a bug in documentation).
Therefore you should check every node you want to transform if it equals range's startContainer or endContainer and if yes - transform only that part of it which is inside range.
Note: I don't know walker's internals and I'm not sure whether you can modify DOM while iterating over it. I'd recommend first caching nodes and then making changes.

Sum of DOM elements using XPath

I am using MSXML v3.0 in a VB 6.0 application. The application calculates sum of an attribute of all nodes using for each loop as shown below
Set subNodes = docXML.selectNodes("//Transaction")
For Each subNode In subNodes
total = total + Val(subNode.selectSingleNode("Amount").nodeTypedValue)
Next
This loop is taking too much time, sometime it takes 15-20 minutes for 60 thousand nodes.
I am looking for XPath/DOM solution to eliminate this loop, probably
docXML.selectNodes("//Transaction").Sum("Amount")
or
docXML.selectNodes("Sum(//Transaction/Amount)")
Any suggestion is welcomed to get this sum faster.
// Open the XML.
docNav = new XPathDocument(#"c:\books.xml");
// Create a navigator to query with XPath.
nav = docNav.CreateNavigator();
// Find the sum
// This expression uses standard XPath syntax.
strExpression = "sum(/bookstore/book/price)";
// Use the Evaluate method to return the evaluated expression.
Console.WriteLine("The price sum of the books are {0}", nav.Evaluate(strExpression));
source: http://support.microsoft.com/kb/308333
Any solution that uses the XPath // pseudo-operator on an XML document with 60000+ nodes is going to be quite slow, because //x causes a complete traversal of the tree starting at the root of the document.
The solution can be speeded up significantly, if a more exact XPath expression is used, that doesn't include the // pseudo-operator.
If you know the structure of the XML document, always use a specific chain of location steps -- never //.
If you provide a small example, showing the specific structure of the document, then many people will be able to provide a faster solution than any solution that uses //.
For example, if it is known that all Transaction elements can be selected using this XPath expression:
/x/y/Transaction
then the evaluation of
sum(/x/y/Transaction/Amount)
is likely to be significantly faster than Sum(//Transaction/Amount)
Update:
The OP has revealed in a comment that the structure of the XML file is quite simple.
Accordingly, I tried with a 60000 Transaction nodes XML document the following:
/*/*/Amount
With .NET XslCompiledTransform (Yes, I used XSLT as the host for the XPath engine) this took 220ms (milliseconds), that means 0.22 seconds, to produce the sum.
With MSXML3 it takes 334 seconds.
With MSXML6 it takes 76 seconds -- still quite slow.
Conclusion: This is a bug in MSXML3 -- try to upgrade to another XPath engine, such as the one offered by .NET.