Calculate Range for Diagnostic report - visual-studio-code

I have this JSON
{
"components": [
"component1",
"component2",
"component3"
],
"validFrom": "someDate"
}
I would like to calculate the Range for VSCode so that I can report Diagnostics in my extension.
How can I calculate the Range, i.e. for "component1"? Some utility function should return something like (startLine: 3, startCharacter: 5, endLine: 3, endCharacter: 5 + component1.length).

With the jsonc-parser, which is also used by VS Code itself to parse JSON content btw., you can parse the document and get the range of an element.
This sample demonstrates how to get the range of "component1":
import { findNodeAtLocation, parseTree } from "jsonc-parser";
...
//Parse JSON of a TextDocument
const rootNode = parseTree(textDocument.getText());
// Find first element of the "components" array
const firstComponent = findNodeAtLocation(rootNode, ["components", 0]);
const start = textDocument.positionAt(firstComponent.offset);
const end = textDocument.positionAt(firstComponent.offset + firstComponent.length)
const range = new Range(start, end);
(Please note: I skipped any check for undefined)

Positioning information is usually provided by a parser. It determines the individual tokens in the input and their location. This can then be used to generate Monaco ranges for various purposes (code completion, error diagnostics, edit actions etc.).

Related

Email Pdf attachments to Google sheet

I am looking for something that allows me from a mail PDF attachment to get a data in a google sheet.
We all often get PDF attachments in our email and it will be great if we get the entire data in a google sheet.
DO let me know if there is anything like this
Explanation:
Your question is very broad and it is impossible to give a specific answer because that answer would depend on the pdf but also on the data you want to fetch from that, besides all the other details you skipped to mention.
Here I will provide a general code snippet which you can use to get the pdf from the gmail attachments and then convert it to text (string). For this text you can use some regular expressions (which have to be very specific on your use case) to get the desired information and then put it in your sheet.
Code snippet:
The main code will this one. You should only modify this code:
function myFunction() {
const queryString = "label:unread from example#gmail.com" // use your email query
const threads = GmailApp.search(queryString);
const threadsMessages = GmailApp.getMessagesForThreads(threads);
const ss = SpreadsheetApp.getActive();
for (thr = 0, thrs = threads.length; thr < thrs; ++thr) {
let messages = threads[thr].getMessages();
for (msg = 0, msgs = messages.length; msg < msgs; ++msg) {
let attachments = messages[msg].getAttachments();
for (att = 0, atts = attachments.length; att < atts; ++att) {
let attachment_Name = attachments[att].getName();
let filetext = pdfToText( attachments[att], {keepTextfile: false} );
Logger.log(filetext)
// do something with filetext
// build some regular expression that fetches the desired data from filetext
// put this data to the sheet
}}}
}
and pdfToText is a function implemented by Mogsdad which you can find here. Just copy paste the code snippet provided in that link together with myFunction I posted in this answer. Also you have some options which you can use that are very well explained in the link I provided. Important thing to note, to use this library you need to enable the Drive API from the resources.
This will get you started and if you face any issues down the road which you can't find the solution for, you should create a new post here with the specific details of the problem.

How to run babel's babylon.parse on multiple files

I can load one file and traverse it with babel, it goes something like this:
var babylon = require("babylon");
let contents = fs.readFileSync("example.js","utf-8");
let ast = babylon.parse(contents);
Now the question is, how can I get the AST (Abstract Syntax Tree) if I have multiple files in my program.
main.js
export const getFoo(){
return "a"
}
example.js
import {getFoo} from './main'
let bar = getFoo() + "baz";
Obviously I would like to see the function declaration and the function call expression into the same AST, but also at the same time getting the line numbers and columns (node.loc) information to also show the specific file.
You can concatenate the AST from several files if you know their paths and can load them.
import {parse} from '#babel/parser';
const a = 'var a = 1;'; // or fs.readFileSync("a.js","utf-8");
const b = 'var b = 2;'; // or fs.readFileSync("b.js","utf-8");
const astA = parse(a, { sourceFilename: 'a.js' });
const astB = parse(b, { sourceFilename: 'b.js' });
const ast = {
type: 'Program',
body: [].concat(astA.program.body, astB.program.body)
};
Source example
But I can't find out how to get AST from several files without loading them directly. I tried to write a babel plugin to analyze code from an imported file and I haven't realized how to do that.

How to reject numeric values in Lucene.net?

I want to know whether is it possible to reject numeric phrases or numeric values while indexing or searching in Lucene.net.
For example (this is one line),
Hi all my no is 4756396
Now, when I index or search it should reject the numeric value 4756396 to be indexed or searched. I tried making a custom stop word list with 1, 2, 3, 4, 5, 6, etc, but I guess it will only ignore if a single number will appears.
You can copy the StandardAnalyzer and customize the grammar (simple JFlex stuff) to reject number tokens. If you do that, you'll need to port back the analyzer to Java since JFlex will generate java code, tho you could give it a try with C# Flex.
You could also write a TokenFilter that scans tokens one by one and rejects them if they are numbers. If you wanna filter only whole numbers and still retain numbers that are for example separate by hyphens, the filter could simply attempt a double.TryParse() and if it fails you accept the Token. A more robust and customizable solution would still use a lexical parser.
Edit:
Heres a quick sample of what I mean, with a little main method that shows how to use it. In this I used a TryParse() to filter out tokens, if it were for a more complex production system I'd use a lexical parser system. (take a look at C# Flex for that)
public class NumericFilter : TokenFilter
{
private ITermAttribute termAtt ;
public NumericFilter(TokenStream tokStream)
: base(tokStream)
{
termAtt = AddAttribute<ITermAttribute>();
}
public override bool IncrementToken()
{
while (base.input.IncrementToken())
{
string term = termAtt.Term;
double res ;
if(double.TryParse(term, out res))
{
// skip this token
continue;
}
// accept this token
return true;
}
// no more token in the stream
return false;
}
}
static void Main(string[] args)
{
RAMDirectory dir = new RAMDirectory();
IndexWriter iw = new IndexWriter(dir, new KeywordAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
Document d = new Document();
Field f = new Field("text", "", Field.Store.YES, Field.Index.ANALYZED);
d.Add(f);
// use our Filter here
f.SetTokenStream(new NumericFilter(new LowerCaseFilter(new WhitespaceTokenizer(new StringReader("I have 300 dollars")))));
iw.AddDocument(d);
iw.Commit();
IndexReader reader = iw.GetReader();
// print all terms in the text field
TermEnum terms = reader.Terms(new Term("text", ""));
do
{
Console.WriteLine(terms.Term.Text);
}
while (terms.Next());
reader.Dispose();
iw.Dispose();
Console.ReadLine();
Environment.Exit(42);
}

Protovis - dealing with a text source

lets say I have a text file with lines as such:
[4/20/11 17:07:12:875 CEST] 00000059 FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on D:/Prgs/testing/WebSphere/AppServer/profiles/ProcCtr01/logs/ffdc/server1_3d203d20_11.04.20_17.07.12.8755227341908890183253.txt com.test.testserver.management.cmdframework.CmdNotificationListener 134
[4/20/11 17:07:27:609 CEST] 0000005d wle E CWLLG2229E: An exception occurred in an EJB call. Error: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
com.lombardisoftware.core.TeamWorksException: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
at com.lombardisoftware.server.ejb.persistence.CommonDAO.assertNotNull(CommonDAO.java:70)
Is there anyway to easily import a data source such as this into protovis, if not what would the easiest way to parse this into a JSON format. For example for the first entry might be parsed like so:
[
{
"Date": "4/20/11 17:07:12:875 CEST",
"Status": "00000059",
"Msg": "FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I",
},
]
Thanks, David
Protovis itself doesn't offer any utilities for parsing text files, so your options are:
Use Javascript to parse the text into an object, most likely using regex.
Pre-process the text using the text-parsing language or utility of your choice, exporting a JSON file.
Which you choose depends on several factors:
Is the data somewhat static, or are you going to be running this on a new or dynamic file each time you look at it? With static data, it might be easiest to pre-process; with dynamic data, this may add an annoying extra step.
How much data do you have? Parsing a 20K text file in Javascript is totally fine; parsing a 2MB file will be really slow, and will cause the browser to hang while it's working (unless you use Workers).
If there's a lot of processing involved, would you rather put that load on the server (by using a server-side script for pre-processing) or on the client (by doing it in the browser)?
If you wanted to do this in Javascript, based on the sample you provided, you might do something like this:
// Assumes var text = 'your text';
// use the utility of your choice to load your text file into the
// variable (e.g. jQuery.get()), or just paste it in.
var lines = text.split(/[\r\n\f]+/),
// regex to match your log entry beginning
patt = /^\[(\d\d?\/\d\d?\/\d\d? \d\d:\d\d:\d\d:\d{3} [A-Z]+)\] (\d{8})/,
items = [],
currentItem;
// loop through the lines in the file
lines.forEach(function(line) {
// look for the beginning of a log entry
var initialData = line.match(patt);
if (initialData) {
// start a new item, using the captured matches
currentItem = {
Date: initialData[1],
Status: initialData[2],
Msg: line.substr(initialData[0].length + 1)
}
items.push(currentItem);
} else {
// this is a continuation of the last item
currentItem.Msg += "\n" + line;
}
});
// items now contains an array of objects with your data

jqgrid edittype select load value from data

I am using jqgrid in my new project.
In a specific case I need to use a select element in the grid. No problem.
I define the colModel and the column for example like (from wiki)
colModel : [
...
{name:'myname', edittype:'select', editoptions:{value:{1:'One',2:'Two'}} },
...
]
But now when I load my data I would prefer the column "myname" to contain the value 1.
This won't work for me instead it has to contain the value "One".
The problem with this is that the text-part of the select element is in my case localized in the business layer where the colModel is dynamically generated. Also the datatype for the entity which generates the data via EF 4 may not be a string. Then I have to find the correct localized text and manipulate the data result so that the column "myname" does not containt an integer which is typically the case but a string instead with the localized text.
There is no option you can use so that when the data contains the value which match an option in the select list then the grid finds that option and presents the text.
Now the grid presents the value as a text and first when I click edit it finds the matching option and presents the text. When I undo the edit it returns to present the value again.
I started to think of a solution and this is what I came up with. Please if you know a better solution or if you know there is a built in option don't hesitate to answer.
Otherwise here is what I did:
loadComplete: function (data) {
var colModel = grid.getGridParam('colModel');
$.each(colModel, function (index, col) {
if (col.edittype === 'select') {
$.each(grid.getDataIDs(), function (index, id) {
var row = grid.getRowData(id);
var value = row[col.name];
var editoptions = col.editoptions.value;
var startText = editoptions.indexOf(value + ':') + (value + ':').length;
var endText = editoptions.indexOf(';', startText);
if (endText === -1) { endText = editoptions.length; }
var text = editoptions.substring(startText, endText);
row[col.name] = text;
grid.setRowData(id, row);
});
}
});
}
It works and I will leave it like this if nobody comes up with a better way.
You should just include additional formatter:'select' option in the definition of the column. See the documentation for more details.