Intro:
I'm trying to make a html application (.htm) to make some business calculations. The issue that comes is that I need to keep records of everything.
First I found some visual basic scripts to read/write .mdb files, but that was too complicated for me since I have never worked with vbs.
So, I decided to use javascript to read/write .csv file
This is the function I found for reading:
function displayClassList() {
var path="log.csv"
var fso = new ActiveXObject('Scripting.FileSystemObject'),
iStream=fso.OpenTextFile(path, 1, false);
document.getElementById("searchResults").innerHTML="";
while(!iStream.AtEndOfStream) {
var line=iStream.ReadLine();
document.getElementById("searchResults").innerHTML += line + "<br/>";
}
iStream.Close();
}
It works good.
The problem I have is when it comes to writing. I can not append text to a new line in the document. This is the script I got:
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.CreateTextFile("./ClassList.csv", true);
s.WriteLine("helloworld");
s.Close();
}
The problem with this script is that it replaces all the existing text with "helloworld". What I want is to write "helloworld" in new line. Any solution for that?
Also, is there any way to edit a specific line, like replacing all text in line x?
Here are the scripts for download so that you can test them : http://ge.tt/7u5bDAV2/v/0
If you want to append to the file without overwriting the existing contents, you can use the OpenTextFile method - note that the CreateTextFile method you're using truncates the existing contents.
var fso = new ActiveXObject("Scripting.FileSystemObject");
var s = fso.OpenTextFile("./ClassList.csv", 8);
s.WriteLine("helloworld");
s.Close();
There is no easy way of modifying one line of a text file, unless the modifications you're making leave the line the same length, since otherwise if your changes are shorter you will leave part of the old line unchanged, while if your changes are longer you would overwrite the next line.
More importantly, the FileSystemObject does not support seeking, which you would need in order to jump to a specific line.
If you want to modify one line of the file, your best bet is to:
Open the existing file for reading, and also create a new file for writing
Read the existing file line by line, writing the content you want to keep to the new file
Write your modified line(s) to the new file where needed
Close both files, and rename the new file to replace the old one
Having said that, maybe it would be easier for you if your data file was an HTML or XML document rather than a CSV, since you could then use DOM manipulation functions to read and write it.
Generally you use "\n" in your string to create new lines. It represents the newline character in a JS string.
Here's how "lines" work in text files. It's just a long sequence of characters, and one of the possible characters is the newline character. Whatever program renders the file when you view it just knows to show text after a newline character below any text that was before it. You could split the string you read by the newline character and get an Array representing each line and work with it that way. Then to write you'd join that Array by the newline character and write the resulting string.
Note that some programs require "\r\n" to represent a proper newline and won't render new lines for just a "\n"...so try "\r\n" as the newline if you're having trouble getting newlines to work for the program you use to view the text files.
EDIT: Since you don't seem to believe me I'll just prove it to you with code. I did it with an .hta file, but the concept is the same.
Made a text file "myText.txt" and an .hta file with the code in it. The text file held the contents:
This is line 1
Line 2
the third line
line 4 and stuff
fifth line
Then in my code I made these two functions for easily reading and writing:
function getFile(fname)
{
var opener = new ActiveXObject("Scripting.FileSystemObject");
var pointer = opener.OpenTextFile(fname, 1, true);
var cont = pointer.ReadAll();
pointer.Close();
return cont;
}
function setFile(fname, content)
{
var opener = new ActiveXObject("Scripting.FileSystemObject");
var pointer = opener.OpenTextFile(fname, 2, true);
pointer.WriteLine(content);
pointer.Close();
}
For the programs I was using it uses "\r\n" for the newline. So that's what the example will use. I simply utilize splitting and joining on the string of content to edit whatever line of it I choose:
var content = getFile('myFile.txt'); // read it
var lineArr = content.split('\r\n'); // now we have an array of the file's lines
lineArr[2] = 'NEW LINE CONTENT!'; // editing third line (indexed from 0)
var newContent = lineArr.join('\r\n'); // make it text again with newlines
setFile("myFile.txt", newContent); // write it
Now the text file looks like this:
This is line 1
Line 2
NEW LINE CONTENT!
line 4 and stuff
fifth line
Bam. Editing individual lines in a text format file by understanding how newlines work in text.
Related
Let's say I have a text file called example.exe that is like this:
Line 1 Stuff
Line 2 Stuff
(more lines here)
Line N (Last Line) Stuff
(empty line \n)
I want to be able to read the last line of the file only, so in this case "Line N (Last Line) Stuff" and store it inside a string. Also, I do know you can read line-by-line, but I want to reduce runtime and not have out of memory errors occur as the text file gets bigger. Anybody want to help me with this? I would prefer no this done using require('fs').
Assuming you store the content in a variable content you can split the content by lines...
var lines = content.split("\n")
...and check if the last line is empty...
var lastLine = lines[lines.length-1].length ? lines[lines.length-1] : lines[lines.length-2]
I have a text like this:
Last login: today
cat file
testMachine:root:/root# cat file
File contents
testMachine:root:/root#
And I need to retrieve the information like this:
testMachine:root:/root# cat file
File contents
Stripping away the last line is easy, but the amount of lines I need to remove at start is arbitrary, and I need to remove everything up until the first cue word, which is the machine name, that is known and stored.
I have tried substring() but it strips line by line instead of treating the whole text as one, and removes the host name too, which should remain there. I tried replace() too, but I am not familiar with regex, so the result is a memory exception.
EDIT 1: It seems to be important to note that using a JS for Java engine (In this case I'm using Rhino) means the result isn't the same as you get in web. This was found out after an answer below, which works perfectly on web, doesn't even run on the desktop app.
const text = `
Last login: today
cat file
testMachine:root:/root# cat file
File contents
testMachine:root:/root#`;
const cueWord = "testMachine:root"
const idx = text.indexOf(cueWord);
let restOftheString = text.substring(idx).split("\n");
restOftheString.pop()
console.log(restOftheString.join("\n"))
I have a web app in Node.js/MySQL where users can upload their stories. They write in an HTML textarea tag. Now I'm trying to get the uploaded from the database using ejs into a script tag so I can do further 'processes'
<script>
var text = "<%=story.Content%>",
result = anchorme.js(text);
document.getElementById('story-content').innerHTML = twemoji.parse(result);
</script>
Problem is if the user hit enter to start on a new line while writing. It'll give me an error here in the text variable and nothing will be printed so how do I fix this?
If you view source on the page so that you can see how the browser receives it, you'll see something like this - note the line feeds:
var text = "I am a story over multiple lines
and that's what javascript gets confused about
because it can't figure out where the closing quotes are.
Let's not even go into what could happen when someone uses quotes!"
So you really just need a way to pass the story content to javascript without it breaking the page. Instead of just pushing out the string like this...
var text = "<%=story.Content%>"
...you can pass stuff to javascript in JSON format as that allows and escapes newlines into \r\n and quotes into \" and so-on. Note the use of <%- rather than <%= here because you don't want it to pass escaped HTML:
var text = <%-JSON.stringify({ content: story.Content })%>.content;
That passes an object with a nicely escaped string in it to your inline script for it to carry on processing.
I currently have this in my editor..
* Line one
* Line two
some more info
Which sits in the database like this
* Line one\r\n* Line two\r\nsome more info
I am using Markdown package to turn the markdown to HTML to display on my site, this works fine.
However it is ignoring the line breaks, thus giving me this output...
<ul><li>Line one</li><li>Line two\r\nsome more info</li></ul>
When the output I want is...
<ul><li>Line one</li><li>Line two</li></ul>some more info
I guess i need to make a 'multiline string' from my single line before i run it through the markdown?
Any thoughts on the best approach?
Currently using this code
var markdown = require( "markdown" ).markdown;
var unMarkdownDescriptions = function(description){
//Check if currently contains HTML.
if(typeof description !== "undefined"){
if(description.indexOf("<") !=-1){
return description;
}else{
return html_content = markdown.toHTML(description);
}
}else{
return '';
}
}
Current code check if already stored as HTML in DB and ignores them (we are migrated from HTML to MD, the HTML generated on the ERP is dodgy at the best of times!)
However it is ignoring the line breaks
That's how it should behave, according to the Markdown spec:
A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line — a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.
The implication of the "one or more consecutive lines of text" rule is that Markdown supports "hard-wrapped" text paragraphs. This differs significantly from most other text-to-HTML formatters (including Movable Type’s “Convert Line Breaks” option) which translate every line break character in a paragraph into a <br /> tag.
To get the output you want, simply include a blank line after your list:
* Line one
* Line two
some more info
I am trying to preserve some XML entities when parsing XML files in javascript. The following code snippet illustrates the problem. Is there a way for me to make round-trip parse and retain the XML entities ( is nbsp; html)? This happens in Chrome FF and IE10.
var aaa='<root><div> one two</div></root>'
var doc=new DOMParser().parseFromString(aaa,'application/xml')
new XMLSerializer().serializeToString(doc)
"<root><div> one two</div></root>"
The issue is I am taking some chunks out of html and storing them in xml, and then I want to get the spaces back in XML when I'm done.
Edit:
As Dan and others have pointed out, the parser replaces it with the ascii code 160, which to my eyes looks like an ordinary space but:
var str1=new XMLSerializer().serializeToString(doc)
str1.charCodeAt(15)
160
So where ever my application is losing the spaces, it is not here.
You can use a ranged RegExp to turn the special chars back into xml representations.
as a nice re-usable function:
function escapeExtended(s){
return s.replace(/([\x80-\xff])/g, function (a, b) {
var c = b.charCodeAt();
return "&#" + b.charCodeAt()+";"
});
}
var aaa='<root><div> one two</div></root>'
var doc=new DOMParser().parseFromString(aaa,'application/xml')
var str= new XMLSerializer().serializeToString(doc);
alert(escapeExtended(str)); // shows: "<root><div> one two</div></root>"
Note that HTML entities (ex quot;) will lose their symbol name, and be converted to XML entities (the &#number; kind). you can't get back the names without a huge conversion table.