I have below data in a text file:
Details_A
name: A1
Valid: A1_Value
name: A2
Valid: A2_Value
Details_A2
name: A2
Valid: A2_Value
name: A2
Valid: A2_Value
which I am trying to convert into in below html table:
Details
You can use awk like this :
awk 'BEGIN {
x = 0;
print "<table border="1">"
}
{
if (NF == 1){
print "<tr ><td colspan="2">"$i"</td>";
print "</tr>"
} else {
if (x == 0){
x++;
print "<tr><td>"$i"</td>"
} else {
x = 0;
print "<td>"$i"</td></tr>"
}
}
}
END {
print "</table>"
}' input.txt > table.html
Feel free to add any additional style
For older version of awk, you can use the following, tested on an awk implementation of 2009-11-26 (from one-true-awk) :
awk 'BEGIN {
x = 0;
y = 0;
print "<table border="1">"
}
{
for (i = 1; i<=NF ; i++){
if (NF == 1){
print "<tr ><td colspan="2">"$i"</td></tr>";
} else {
if (x == 0 && y == 0){
print "<tr><td>"$i" ";
x++;
}
else if (x == 0 && y == 1){
print "<td>"$i" ";
x++;
}
else if (x==(NF-1)){
x = 0;
y++;
if (y == 2){
y = 0;
print ""$i"</td></tr>";
}
else{
print ""$i"</td>";
}
}
else {
print ""$i" ";
x++;
}
}
}
}
END {
print "</table>"
}' input.txt > table.html
For this last version, x is incremented at each space delimiter until we reach NF-1 which is the last word and we should put an ending </td>. The decision for the ending </tr> depends on the value of y which is incremented at each line and re-initialized when the max count of <td> is reached (here 2 <td> per <tr>)
Related
on the server-side, using Nodejs. I receive a text message containing HTML. I want a function that converts the html to plain text. And please don't tell me to add the tag <plaintext> or <pre>. (convert_to_html function doesn't exist in nodejs)
socket.on('echo', (text) => {
plaintext = convert_to_html(text);
socket.emit('echo', {
message: plaintext
});
});
ideal results:
input: <h1>haha i am big</h1>
plaintext(what i want plaintext to be): <h1 &60;haha i am big </h1 &60;
output: <h1>haha i am big</h1>
current result:
input: <h1>haha i am big</h1>
plaintext: <h1>haha i am big</h1>
output: haha i am big
You can use the insertAdjacementHTML method on the browser side, here you go an example
socket.on("response", function (msg) {
const messages = document.getElementById("messages");
messages.insertAdjacentHTML("beforebegin", msg);
window.scrollTo(0, document.body.scrollHeight);
});
still don't have a proper solution. while i wait for one, i will use reserved characters as a temporary solution.
https://devpractical.com/display-html-tags-as-plain-text/#:~:text=You%20can%20show%20HTML%20tags,the%20reader%20on%20the%20browser.
function parse_to_plain_text(html){
var result = "";
for (var i = 0; i < html.length; i++) {
var current_char = html[i];
if (current_char == ' '){
result += " "
}
else if (current_char == '<'){
result += "<"
}
else if (current_char == '>'){
result += ">"
}
else if (current_char == '&'){
result += "&"
}
else if (current_char == '"'){
result += """
}
else if (current_char == "'"){
result += "'"
}
else{
result += current_char;
}
}
return result;
}
I have this file.csv
"201707"|"51976551"|1|0|1|"20170702"
"201707"|"51955194"|1|0|0|"20170702"
"201707"|"51923555"|1|0|1|"20170702"
"201707"|"51976551"|1|0|1|"20170703"
"201707"|"51955194"|1|0|0|"20170703"
"201707"|"51923555"|1|0|1|"20170703"
"201707"|"51960597"|1|0|0|"20170703"
And my hope result is group by the number and sum the column 3, 4 and 5
"201707"|"51976551"|2|0|2
"201707"|"51955194"|2|0|0
"201707"|"51923555"|2|0|2
"201707"|"51960597"|1|0|0
I've tried with:
cat file.csv | awk -F"|" '
{ a[$2] += $3 }
END {
for (i in a) {
printf "%s|%s\n", i, a[i];
}
}
'
And the result is:
"51976551"|2
"51955194"|2
"51923555"|2
"51960597"|1
Only shows the sum of third column, but I need 2 columns more.
what should I do in this case?
Try:
$ awk -F"|" '{ a[$1 OFS $2]+=$3; b[$1 OFS $2]+=$4; c[$1 OFS $2]+=$5 }
END {
for (i in a) {
print i, a[i], b[i], c[i];
}
}
' OFS=\| file.csv
"201707"|"51976551"|2|0|2
"201707"|"51960597"|1|0|0
"201707"|"51923555"|2|0|2
"201707"|"51955194"|2|0|0
How it works
-F"|"
This sets the field separator on input to |.
a[$1 OFS $2]+=$3; b[$1 OFS $2]+=$4; c[$1 OFS $2]+=$5
This keeps track of the totals of the third, fourth, and fifth columns.
END {
for (i in a) {
print i, a[i], b[i], c[i];
}
}
This prints out the results.
OFS=\|
This tells awk to use | as the field separator on output.
To Preserve order:
By processing in END block
awk 'BEGIN{
FS=OFS="|"
}
{
k = $1 OFS $2;
if(!(k in t)){
o[++c]=k;
t[k]
}
for(i=3; i<=5; i++)
a[k OFS i]+=$i
}
END{
for(i=1; i in o; i++)
{
printf "%s", o[i];
for(j=3; j<=5; j++)
printf "%s%s", OFS, a[o[i] OFS j];
print ""
}
}
' infile
Or by reading same file twice (GNU awk)
awk 'BEGIN{
FS=OFS="|"
}
function ps(f)
{
for(i=3;i<=5;i++)
if(f)
{
a[k OFS i]+=$i;
t[k]
}else
s=(s ? s OFS :"") a[k OFS i]
}
{
k=$1 OFS $2
}
FNR==NR{
ps(1);
next
}
k in t{
s="";
ps();
print k, s;
delete t[k]
}
' infile infile
Input:
$ cat input
"201707"|"51976551"|1|0|1|"20170702"
"201707"|"51955194"|1|0|0|"20170702"
"201707"|"51923555"|1|0|1|"20170702"
"201707"|"51976551"|1|0|1|"20170703"
"201707"|"51955194"|1|0|0|"20170703"
"201707"|"51923555"|1|0|1|"20170703"
"201707"|"51960597"|1|0|0|"20170703"
Output-1:
$ awk 'BEGIN{FS=OFS="|"}{k = $1 OFS $2; if(!(k in t)){o[++c]=k; t[k]} for(i=3; i<=5; i++)a[k OFS i]+=$i}END{for(i=1; i in o; i++){printf "%s", o[i]; for(j=3; j<=5; j++)printf "%s%s", OFS, a[o[i] OFS j]; print ""}}' infile
"201707"|"51976551"|2|0|2
"201707"|"51955194"|2|0|0
"201707"|"51923555"|2|0|2
"201707"|"51960597"|1|0|0
Output-2:
$ awk 'BEGIN{FS=OFS="|"}function ps(f){for(i=3;i<=5;i++)if(f){ a[k OFS i]+=$i; t[k] }else s=(s ? s OFS :"") a[k OFS i]}{k=$1 OFS $2}FNR==NR{ps(1); next}k in t{s=""; ps(); print k, s; delete t[k] }' infile infile
"201707"|"51976551"|2|0|2
"201707"|"51955194"|2|0|0
"201707"|"51923555"|2|0|2
"201707"|"51960597"|1|0|0
I have atable in mysql database i'm fetching it to a html
print "<table>\n";
$result = $con->query($query); //return only the first row (we only need field names)
$row = $result->fetch(PDO::FETCH_ASSOC);
print "<tr>\n";
foreach ($row as $field => $value){
print "<th>$field</th>\n";
} // end foreach
print "</tr>\n"; //second query gets the data
$data = $con->query($query);
$data->setFetchMode(PDO::FETCH_ASSOC);
foreach($data as $row){
print " <tr>\n";
foreach ($row as $name=>$value){
print "<td>$value</td>\n";
} // end field loop
print "</tr>\n"; } // end record loop
print "</table>\n";
}
catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
} // end try
i have 2 columns that have a boolean value, i want that if column 6 = '0' then display x color:red; else display ✔ color:green;
Final Code
foreach ($row as $name=>$value){
if (($name == "paid" || $name == "added") && $value == "0"){
print "<td><span style='color: red;'>X</span></td>\n";
}
elseif (($name == "paid" || $name == "added") && $value == "1"){
print "<td><span style='color: lime;'>✔</span></td>\n";
}
else {
print "<td>$value</td>\n";
}
} // end field loop
Try:
foreach ($row as $name=>$value){
if ($name == "Column 6"){
if ($value == "0") {
print "<td><span style='color: red;">X</span></td>\n";
}
else {
print "<td>✔</td>\n";
}
}
else {
print "<td>$value</td>\n";
}
} // end field loop
There's no good way to colorize checkboxes, unless you want to use some complex css. However you could try and utilize before and after CSS for checkboxes as shown here: CSS ''background-color" attribute not working on checkbox inside <div>
How can I take the output of hg history and convert it into a dot file?
You are looking for this extension.
I wrote a script to do this (and called it hghistory2dot.pl). See its usage below the code:
#!/usr/bin/perl
print "digraph {\n";
$first = 1;
$cset = ();
sub printedge {
my $one = csetstr(shift(#_));
my $two = csetstr(shift(#_));
print $one, " -> ", $two, ";\n";
}
sub csetstr {
my $csetid = shift(#_);
$csetid =~ s/\s//;
$csetid =~ s/\\n//;
return "cset_" . $csetid;
}
while($line = <> ) {
if (!($line eq "\n") ) {
$line =~ s/\n/\\n/;
push(#cset, $line);
}
else {
print csetstr($current), " [shape=record label=\"", #cset, "\"];\n";
#cset = ();
}
if( $line =~ m/^changeset/ ) {
#arr = split(/:/, $line);
$arr[2] =~ s/\s//;
if( ! $parent_found && ! $first) {
#previous changeset had no defined parent; therefore this one is the implied parent.
printedge($current, $arr[2]);
}
$current = $arr[2];
$parent_found = 0;
$first = 0;
}
elsif($line =~ m/^parent/) {
$parent_found = 1;
#arr = split(/:/, $line);
$arr[2] =~ s/\s//;
printedge($current, $arr[2]);
}
}
print "}\n";
hg history | hghistory2dot.pl | dot -Tpng > tree.png
I have a page that users are able to add xml markup into a text area input. I'd like after they enter it that it be color-coded and formatted as xml would look in an IDE such as Visual Studio. Anybody know of a script or tool that would allow for this within a client-side browser?
Take a look at CodeMirror, a syntax-highlighting editor in Javascript for browsers. This is an example for XML editing.
Short answer: you can't.
Not in an TEXTAREA, as the one here in SO.
The example in SO is very good, as it has a TEXTAREA where we type the text, and a DIV box below where you can see what you type formatted.
You could also go through the contentEditable = "true", but it's a real pain to do it properly...
A nice option would be this: vkBeautify
Here is an example:
(function() {
function createShiftArr(step) {
var space = ' ';
if ( isNaN(parseInt(step)) ) { // argument is string
space = step;
} else { // argument is integer
switch(step) {
case 1: space = ' '; break;
case 2: space = ' '; break;
case 3: space = ' '; break;
case 4: space = ' '; break;
case 5: space = ' '; break;
case 6: space = ' '; break;
case 7: space = ' '; break;
case 8: space = ' '; break;
case 9: space = ' '; break;
case 10: space = ' '; break;
case 11: space = ' '; break;
case 12: space = ' '; break;
}
}
var shift = ['\n']; // array of shifts
for(ix=0;ix<100;ix++){
shift.push(shift[ix]+space);
}
return shift;
}
function vkbeautify(){
this.step = ' '; // 4 spaces
this.shift = createShiftArr(this.step);
};
vkbeautify.prototype.xml = function(text,step) {
var ar = text.replace(/>\s{0,}</g,"><")
.replace(/</g,"~::~<")
.replace(/\s*xmlns\:/g,"~::~xmlns:")
.replace(/\s*xmlns\=/g,"~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if(ar[ix].search(/<!/) > -1) {
str += shift[deep]+ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
str += ar[ix];
if(!inComment) deep--;
} else
// <elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// </elm> //
if(ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
} else
// <elm/> //
if(ar[ix].search(/\/>/) > -1 ) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if(ar[ix].search(/<\?/) > -1) {
str += shift[deep]+ar[ix];
} else
// xmlns //
if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += shift[deep]+ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
}
window.vkbeautify = new vkbeautify();
})();
var xmlData = '<note><to>Tove</to><from>Jani</from><heading>Reminder</heading><body>Don\'t forget me this weekend!</body></note>';
xmlData = vkbeautify.xml(xmlData);
$('textarea').val(xmlData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea cols="30" rows="10"></textarea>