[x3d-public] announce: updated encoding, X3D to JSON Stylesheet Converter: string arrays, whitespace, UTF-8, Script #source

Don Brutzman brutzman at nps.edu
Tue Nov 17 06:21:16 PST 2015


[Summary: further analysis of Script #source into JSON]

OK thanks.  This is corroborated by Illustrated EcmaScript 5 reference at very end of paragraph 7.8.4

http://es5.github.io/#x7.8.4
"NOTE A line terminator character cannot appear in a string literal, except as part of a LineContinuation to produce the empty character sequence. The correct way to cause a line terminator character to be part of the String value of a string literal is to use an escape sequence such as \n or \u000A."

However this would seem to be contradicted by "railroad track" diagram for JSON strings
http://www.web3d.org/x3d/stylesheets/X3dToJson.html#strings

but, as you indicate, section 9. Strings in JSON spec says
http://www.ecma-international.org/publications/files/ecma-st/ECMA-404.pdf

"9 String
A string is a sequence of Unicode code points wrapped with quotation marks (U+0022). All characters may be
placed within the quotation marks except for the characters that must be escaped: quotation mark (U+0022),
reverse solidus (U+005C), and the control characters U+0000 to U+001F."

newline characters are within that last range, U+000A.

Stackoverflow is pretty conclusively "no" on this topic:
http://stackoverflow.com/questions/2392766/multiline-strings-in-json

There is an alternative approach in the post there, an array of independently quoted single-line strings, which requires slightly special handling to reconstruct.  An option I guess, but seems nonstandard.  Not surprisingly some programmers found it necessary to resort to that option so that other language parsers don't explode from exceedingly long lines.

More general detail also found on wikipedia under Newline.
https://en.wikipedia.org/wiki/Newline#Unicode

However a jslinterrors.com entry is also interesting:
https://jslinterrors.com/unclosed-string
[...] "makes use of the multiline strings allowed by ECMAScript 5"

... so maybe there is another option at some point, but am not seeing it.

i'll put a switch in the stylesheet to keep original form as an option:

     <xsl:param name="sourceOneLine"><xsl:text>true</xsl:text></xsl:param>

and it would appear that we have to default to the \n megaline form.  #source replacement method added to stylesheet, example attached.  at least it quiets jslint.  if \n obfuscation keeps javascript engines somehow happier than every other language parser then we mere mortals have no right to criticize.  :(

example output:

http://X3dGraphics.com/examples/X3dForAdvancedModeling/GeometricShapes/ParallelepipedPrototype.json

             "-children":[
               { "Script":
                 {
                   "@DEF":"ParallelepipedScript",
                   "field": [
                     {
                       "@name":"point",
                       "@accessType":"inputOutput",
                       "@type":"MFVec3f"
                     }
                   ],
                   "IS": {
                     "connect": [
                       {
                         "@nodeField":"point",
                         "@protoField":"point"
                       }
                     ]
                   },
                   "#source":"\n          \necmascript:\nfunction initialize ()\n{\n    checkCoordinatePoints ();\n}\nfunction checkCoordinatePoints ()\n{\n    // A parallelepiped has three sets of four parallel edges; the edges within each set are of equal length.\n    // Quality assurance: check that lengths of corresponding sides match.\n    \n    edge01 = length2(point[0], point[1]); // top\n    edge12 = length2(point[1], point[2]);\n    edge23 = length2(point[2], point[3]);\n    edge30 = length2(point[3], point[0]);\n    edge45 = length2(point[4], point[5]); // bottom\n    edge56 = length2(point[5], point[6]);\n    edge67 = length2(point[6], point[7]);\n    edge74 = length2(point[7], point[4]);\n    edge04 = length2(point[0], point[4]); // sides\n    edge15 = length2(point[1], point[5]);\n    edge26 = length2(point[2], point[6]);\n    edge37 = length2(point[3], point[7]);\n    \n    epsilon = edge01 * 0.001;\n    \n    if      ((Math.abs(edge01 - edge23) > epsilon) ||\n 
        
     (Math.abs(edge23 - edge67) > epsilon) ||\n             (Math.abs(edge67 - edge45) > epsilon) ||\n             (Math.abs(edge45 - edge01) > epsilon))\n         Browser.println ('Warning, mismatched parallelopiped sides 02/33/45/67');\n    else if ((Math.abs(edge30 - edge12) > epsilon) ||\n             (Math.abs(edge12 - edge56) > epsilon) ||\n             (Math.abs(edge56 - edge74) > epsilon) ||\n             (Math.abs(edge74 - edge30) > epsilon))\n         Browser.println ('Warning, mismatched parallelopiped sides 30/12/56/74');\n    else if ((Math.abs(edge04 - edge15) > epsilon) ||\n             (Math.abs(edge15 - edge26) > epsilon) ||\n             (Math.abs(edge26 - edge37) > epsilon) ||\n             (Math.abs(edge37 - edge04) > epsilon))\n         Browser.println ('Warning, mismatched parallelopiped sides 04/15/26/37');\n}\nfunction length2 (pointA, pointB)\n{    \n    return Math.sqrt((pointA.x - pointB.x)*(pointA.x - pointB.x) +\n                     (pointA.y - p
 ointB.y)
*(pointA.y - pointB.y) +\n                     (pointA.z - pointB.z)*(pointA.z - pointB.z));\n}\nfunction set_point (eventValue)\n{\n   // input eventValue received for inputOutput field\n    point = eventValue;\n    checkCoordinatePoints ();\n}\n\n"
                 }
               }
             ]

oh joy: running the conversions found jslint complaining about tab characters also.  replaced with \t.

let the unreadability ensue, i guess...



On 11/15/2015 11:11 PM, John Carlson wrote:
> It’s likely that you have to convert end-of-line to “\n”  see JSON spec.
>
> John
>
>>
>> The result below looks good to me, according to the JSON specification.  However jslint balks... is it really an error, perhaps an overzealous jslint configuration setting controls this?
>>
>> Console:
>>> C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForAdvancedModeling/GeometricShapes//ParallelepipedPrototype.x3d processing with X3dToJson stylesheet
>>> Script ParallelepipedScript contains CDATA source-code text, copied as "#source"
>>> C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForAdvancedModeling/GeometricShapes//ParallelepipedPrototype.json processing with jslint
>>> jslint:C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForAdvancedModeling/GeometricShapes//ParallelepipedPrototype.json:279:29:JavaScript URL.
>>> jslint:C:\x3d-code\www.web3d.org\x3d\content\examples\X3dForAdvancedModeling/GeometricShapes//ParallelepipedPrototype.json:284:10:Unexpected character '(space)'.
>>
>> Excerpt:
>> http://X3dGraphics.com/examples/X3dForAdvancedModeling/GeometricShapes/ParallelepipedPrototype.x3d
>> http://X3dGraphics.com/examples/X3dForAdvancedModeling/GeometricShapes/ParallelepipedPrototype.json
>>
>>             "-children":[
>>               { "Script":
>>                 {
>>                   "@DEF":"ParallelepipedScript",
>>                   "field": [
>>                     {
>>                       "@name":"point",
>>                       "@accessType":"inputOutput",
>>                       "@type":"MFVec3f"
>>                     }
>>                   ],
>>                   "IS": {
>>                     "connect": [
>>                       {
>>                         "@nodeField":"point",
>>                         "@protoField":"point"
>>                       }
>>                     ]
>>                   },
>>                   "#source":"
>> ecmascript:
>> function initialize ()
>> {
>>     checkCoordinatePoints ();
>> }
>> function checkCoordinatePoints ()
>> {
>>     // A parallelepiped has three sets of four parallel edges; the edges within each set are of equal length.
>>     // Quality assurance: check that lengths of corresponding sides match.
>>         edge01 = length2(point[0], point[1]); // top
>>     edge12 = length2(point[1], point[2]);
>>     edge23 = length2(point[2], point[3]);
>>     edge30 = length2(point[3], point[0]);
>>     edge45 = length2(point[4], point[5]); // bottom
>>     edge56 = length2(point[5], point[6]);
>>     edge67 = length2(point[6], point[7]);
>>     edge74 = length2(point[7], point[4]);
>>     edge04 = length2(point[0], point[4]); // sides
>>     edge15 = length2(point[1], point[5]);
>>     edge26 = length2(point[2], point[6]);
>>     edge37 = length2(point[3], point[7]);
>>         epsilon = edge01 * 0.001;
>>         if      ((Math.abs(edge01 - edge23) > epsilon) ||
>>              (Math.abs(edge23 - edge67) > epsilon) ||
>>              (Math.abs(edge67 - edge45) > epsilon) ||
>>              (Math.abs(edge45 - edge01) > epsilon))
>>          Browser.println ('Warning, mismatched parallelopiped sides 02/33/45/67');
>>     else if ((Math.abs(edge30 - edge12) > epsilon) ||
>>              (Math.abs(edge12 - edge56) > epsilon) ||
>>              (Math.abs(edge56 - edge74) > epsilon) ||
>>              (Math.abs(edge74 - edge30) > epsilon))
>>          Browser.println ('Warning, mismatched parallelopiped sides 30/12/56/74');
>>     else if ((Math.abs(edge04 - edge15) > epsilon) ||
>>              (Math.abs(edge15 - edge26) > epsilon) ||
>>              (Math.abs(edge26 - edge37) > epsilon) ||
>>              (Math.abs(edge37 - edge04) > epsilon))
>>          Browser.println ('Warning, mismatched parallelopiped sides 04/15/26/37');
>> }
>> function length2 (pointA, pointB)
>> {
>>     return Math.sqrt((pointA.x - pointB.x)*(pointA.x - pointB.x) +
>>                      (pointA.y - pointB.y)*(pointA.y - pointB.y) +
>>                      (pointA.z - pointB.z)*(pointA.z - pointB.z));
>> }
>> function set_point (eventValue)
>> {
>>    // input eventValue received for inputOutput field
>>     point = eventValue;
>>     checkCoordinatePoints ();
>> }
>> "
>>                 }
>>               }
>>             ]
>>
>> How does it look?  I believe that this is the last major language feature to include, further work will be tuning/improving what is there.
>>
>> =================================================
>>
>> I was able to reduce some of the recursion in the stylesheet, and tried to nudge the memory settings in multiple ways, but the large scenes provoking out-of-memory errors were unimpressed and continue to explode in the same amount of time as before... will continue looking at those configurations.
>>
>> =================================================
>>
>> Closer and closer... comments and improvements remain appreciated and welcome.

all the best, Don
-- 
Don Brutzman  Naval Postgraduate School, Code USW/Br       brutzman at nps.edu
Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA   +1.831.656.2149
X3D graphics, virtual worlds, navy robotics http://faculty.nps.edu/brutzman



More information about the x3d-public mailing list