I embed a text file into my Flex project and read its contents using code like this:
[Embed(source = "../../data/abc.txt", mimeType = "application/octet-stream")]
private var r_Abc:Class;
...
var xx:ByteArray = new r_Abc();
var abc:String = xx.toString();
The contents of the file is abc. The problem is that the string loaded from the file is not comparable to other strings even though when printed or viewed in the debugger (in FlashDevelop) it seems to be perfectly fine.
trace(abc); // abc
trace("abc" == abc); // false
How do I convert it into a proper string? I tried to use the string methods such as substring to create a copy, but that does not seem to be the solution.
Here's my sample:
<?xml version="1.0" encoding="utf-8"?>
<s:Application minWidth="955" minHeight="600"
creationComplete="creationCompleteHandler(event)"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.core.ByteArrayAsset;
import mx.events.FlexEvent;
// my file is "ABC "
// strangely enough if I remove the space at the end the string in code is empty
[Embed(source="data/abc.txt", mimeType="application/octet-stream")]
private var abcFile:Class;
protected function creationCompleteHandler(event:FlexEvent):void
{
var abcByteArray:ByteArrayAsset = ByteArrayAsset(new abcFile());
var abc:String = abcByteArray.readUTFBytes(abcByteArray.length);
trace(abc); // ABC (has a space at the end)
trace(abc == "ABC "); // true, but notice the space at the end
}
]]>
</fx:Script>
</s:Application>
My suggestion is to check for trailing spaces, new lines. Also try to place some sort of an EOF character at the end of the file.
Related
I have a code like this :
// Language = Dart
var someVariable = 'Hello';
var someOtherVariable = 'World';
var str = 'somedomain?x=${someVariable}&y=${someOtherVariable}';
return str;
// Expected:
// somedomain?x=Hello&y=World;
// Actual
// somedomain?x=Hello
If I replace the & character with any alphabets, it is able to successfully concatenate. What am I doing wrong.
This is the actual code which I used in FlutterFlow, and am having issues with:
Future<String> getEventUrlFromReference(BuildContext context, DocumentReference? eventReference) async {
var userId = currentUser?.uid as String;
return "https://somedomain.com/event?eventReference=${eventReference?.id}" + "&invitedBy="+userId;
}
// result: https://somedomain.com/event?eventReference=referencevalue
This was a string encoding issue. I was using the result of my function/code as body text in sms://<number>?&body=<string_containigng_&_character>; The text which is appended to the sms text truncates at the & character, and I made a mistake assuming it's a string concatenation issue.
I have an image in File Cabinet that I want to add to my PDF. I have a script that creates a PDF and adds that image to it.
I tested the link https://system.na2.netsuite.com${imgURL} on my browser and the image loads. However I get a strange error when I try to add it to my PDF below:
var myImageFromFileCabinet = file.load({id:10202});
imgURL = myImageFromFileCabinet.url;
xmlStr = `<body><img src="https://system.na2.netsuite.com${imgURL}"></body>`;
let pdfFile = render.xmlToPdf({ xmlString: xmlStr });
context.response.writeFile({
file: pdfFile,
isInline: true
});
"type":"error.SuiteScriptError","name":"USER_ERROR","message":"Error Parsing XML: The reference to entity "c" must end with the ';' delimiter.
How can I add an image to a PDF?
TLDR: Escape the URL string for use in XML
The root cause of your error is that you are not escaping the URL for use in XML. The & characters in the URL must be escaped as XML/HTML entities. You can do this with the N/xml.escape() function:
const imgURL = xml.escape({xmlText: myImageFromFileCabinet.url});
That said, there were several other issues I had to resolve with this code along the way:
Outer tag must be pdf
The initial error I got when running this code was:
Error Parsing XML: Outer tag is body, should be pdf or pdfset
I fixed this by wrapping the <body> in a <pdf>.
img tag must be closed
Next I needed to close the <img> with </img> (or /> whichever you prefer).
Summary
My full working onRequest looks like:
const onRequest = (context) => {
const myImageFromFileCabinet = file.load({id:1820});
const imgURL = xml.escape({xmlText: myImageFromFileCabinet.url});
const xmlString = `<pdf><body><img src="https://system.na2.netsuite.com${imgURL}"/></body></pdf>`;
const pdfFile = render.xmlToPdf({ xmlString });
context.response.writeFile({
file: pdfFile,
isInline: true
});
};
Note that I've also made some minor changes like renaming variables and adding some const keywords, as well as of course changing the image's internal ID for my own account.
I am trying to do something quite simple. When resharper surrounds selected code with an if statement it does not all a new line at the end:
Original code:
var test = "Hello World";
var test2 = ("Goodbye");
Code wrapped:
if (true)
{
var test = "Hello World";
} var test2 = ("Goodbye");
I want it like this:
if (true)
{
var test = "Hello World";
}
var test2 = ("Goodbye");
I have edited the if surrpound template to have newlines at the end and have even restarted VS. No luck. Example:
How do I add a newline after the surround code?
Is there a list somewhere of the tags available for these templates? Perhaps it is a tag that I need?
I need to take 'href'(tag link location value) value from following pattern html text. need some expert help to do it using typescript
String Text one
"<html><body>docker_command.txt </body></html>"
String Text Two
"<html><body>https://www.facebook.com/ </body></html>"
Something like this?
const a = '"<html><body>docker_command.txt </body></html>"';
const b = '"<html><body>https://www.facebook.com/ </body></html>"';
function getHref(html: string): string|null {
if (!html) {
return null;
}
return html.match(/ href=("|')([^'"]*?)('|")/i)[2];
}
console.log(getHref(a));
console.log(getHref(b));
I have a find and replace script that works no problem when the words don't have any special characters. However, there will be a lot of times where there will be special characters since it's finding names. As of now this is breaking the script.
The script looks for {<some-text>} and attempts to replace the contents (as well as remove the braces).
Example:
text.rtf
Here's a name with special char {Kotouč}
script.ts
import * as fs from "fs";
// Ingest the rtf file.
const content: string = fs.readFileSync("./text.rtf", "utf8");
console.log("content::\n", content);
// The string we are looking to match in file text.
const plainText: string = "{Kotouč}";
// Look for all text that matches the patter `{TEXT_HERE}`.
const anyMatchPattern: RegExp = /{(.*?)}/gi;
const matches: string[] = content.match(anyMatchPattern) || [];
const matchesLen: number = matches.length;
for (let i: number = 0; i < matchesLen; i++) {
// It correctly identifies the targeted text.
const currMatch: string = matches[i];
const isRtfMetadata: boolean = currMatch.endsWith(";}");
if (isRtfMetadata) {
continue;
}
// Here I need a way to escape `plainText` string so that it matches the source.
console.log("currMatch::", currMatch);
console.log("currMatch === plainText::", currMatch === plainText);
if (currMatch === plainText) {
const newContent: string = content.replace(currMatch, "IT_WORKS!");
console.log("newContent:", newContent);
}
}
output
content::
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
\f0\fs24 \cf0 Here's a name with special char \{Kotou\uc0\u269 \}.}
currMatch:: {Kotou\uc0\u269 \}
currMatch === plainText:: false
It looks like ANSI escaping, and I've tried using jsesc but that produces a different string, {Kotou\u010D} instead of what the document produces {Kotou\uc0\u269 \}.
How can I dynamically escape the plainText string variable so that it matches what is found in the document?
What I needed was to deepen my knowledge on rtf formatting as well as general text encoding.
The raw RTF text read from the file gives us a few hints:
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600...
This part of the rtf file metadata tells us a few things.
It is using RTF file formatting version 1. The encoding is ANSI, and specifically cpg1252, also known as Windows-1252 or CP-1252 which is:
...a single-byte character encoding of the Latin alphabet
(source)
The valuable piece of information from that is that we know it is using the Latin alphabet, this will be used later.
Knowing the specific RTF version used I stumbled upon the RTF 1.5 Spec
A quick search on that spec for one of the escape sequences that I was looking into revealed that it was an RTF specific escape control sequence, that is \uc0. So knowing that I was able to then parse what I was really after, \u269. Now I knew it was unicode and had a good hunch that the \u269 stood for unicode character code 269. So I look that up...
The \u269 (char code 269) shows up on this page to confirm. Now I know the character set and what needs done to get the equivalent plain text (unescaped), and there's a basic SO post I used here to get the function started.
Using all this knowledge I was able to piece it together from there. Here's the full corrected script and it's output:
script.ts
import * as fs from "fs";
// Match RTF unicode control sequence: http://www.biblioscape.com/rtf15_spec.htm
const unicodeControlReg: RegExp = /\\uc0\\u/g;
// Extracts the unicode character from an escape sequence with handling for rtf.
const matchEscapedChars: RegExp = /\\uc0\\u(\d{2,6})|\\u(\d{2,6})/g;
/**
* Util function to strip junk characters from string for comparison.
* #param {string} str
* #returns {string}
*/
const cleanupRtfStr = (str: string): string => {
return str
.replace(/\s/g, "")
.replace(/\\/g, "");
};
/**
* Detects escaped unicode and looks up the character by that code.
* #param {string} str
* #returns {string}
*/
const unescapeString = (str: string): string => {
const unescaped = str.replace(matchEscapedChars, (cc: string) => {
const stripped: string = cc.replace(unicodeControlReg, "");
const charCode: number = Number(stripped);
// See unicode character codes here:
// https://unicodelookup.com/#latin/11
return String.fromCharCode(charCode);
});
// Remove all whitespace.
return unescaped;
};
// Ingest the rtf file.
const content: string = fs.readFileSync("./src/TEST.rtf", "binary");
console.log("content::\n", content);
// The string we are looking to match in file text.
const plainText: string = "{Kotouč}";
// Look for all text that matches the pattern `{TEXT_HERE}`.
const anyMatchPattern: RegExp = /{(.*?)}/gi;
const matches: string[] = content.match(anyMatchPattern) || [];
const matchesLen: number = matches.length;
for (let i: number = 0; i < matchesLen; i++) {
const currMatch: string = matches[i];
const isRtfMetadata: boolean = currMatch.endsWith(";}");
if (isRtfMetadata) {
continue;
}
if (currMatch === plainText) {
const newContent: string = content.replace(currMatch, "IT_WORKS!");
console.log("\n\nnewContent:", newContent);
break;
}
const unescapedMatch: string = unescapeString(currMatch);
const cleanedMatch: string = cleanupRtfStr(unescapedMatch);
if (cleanedMatch === plainText) {
const newContent: string = content.replace(currMatch, "IT_WORKS_UNESCAPED!");
console.log("\n\nnewContent:", newContent);
break;
}
}
output
content::
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
\f0\fs24 \cf0 Here\'92s a name with special char \{Kotou\uc0\u269 \}}
newContent: {\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
{\*\expandedcolortbl;;}
\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
\f0\fs24 \cf0 Here\'92s a name with special char \IT_WORKS_UNESCAPED!}
Hopefully that helps others that aren't familiar with character encoding/escaping and it's uses in rtf formatted documents!