Skip to content

Commit

Permalink
use highlights (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedragon authored Jun 16, 2018
1 parent b7e9103 commit 05e826a
Show file tree
Hide file tree
Showing 8 changed files with 451 additions and 16 deletions.
2 changes: 1 addition & 1 deletion kibana-extra/castro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
"eslint-plugin-prefer-object-spread": "^1.2.1",
"eslint-plugin-react": "^7.0.1",
"expect.js": "^0.3.1"

},
"dependencies": {
"highlights": "^3.1.1",
"nodegit": "^0.22.1",
"protobufjs": "^6.8.6"
}
Expand Down
1 change: 1 addition & 0 deletions kibana-extra/castro/proto/Example.proto
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ message Entry {
string path = 1;
string blob = 2;
bool isBinary = 3;
string html = 4;
}

message Person {
Expand Down
35 changes: 35 additions & 0 deletions kibana-extra/castro/public/components/main/code.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

.code .comment {
color: #998;
font-style: italic;
}



.string {
color: #DD0A73;
}

.numeric,
.variable {
color: #00A69B;
}
.keyword,
.primitive,
.modifier {
color: #333;
font-weight: bold;
}

.type,
.class {
color: #0079a5;
font-weight: bold;
}




.parameter {
color: inherit;
}
101 changes: 101 additions & 0 deletions kibana-extra/castro/public/components/main/code.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, {Component} from "react";

import {
EuiButton,
EuiCheckboxGroup,
EuiFieldText,
EuiForm,
EuiFormRow,
EuiTextArea,
EuiSpacer,
EuiButton,
EuiSwitch,
EuiPanel,
EuiCode,
EuiCodeBlock,
} from '@elastic/eui';

import "./code.css"

interface State {
path: string
content: string,
html? : string
}






export default class Code extends Component<any, State> {
constructor(props: any) {
super(props);
this.state = {
path: "HelloWorld.java",
content: `
comments */
import System.out;
class HelloWorld {
public static void main(String[] args){
// some comments
int x = 5;
System.out.println("hello world");
}
}
`,
}
}

highlight() {
const {httpClient} = this.props;
httpClient.post(`../api/castro/highlight/${this.state.path}`, {content: this.state.content}).then(response => {
this.setState({html: response.data})
})
}


render() {
return (
<div>
<EuiForm>
<EuiFormRow
label="Text field"
helpText="Your file name."
>
<EuiFieldText name="first" placeholder={"HelloWorld.java"}
value={this.state.path}
onChange={(e) => this.setState({path: e.target.value})}
/>
</EuiFormRow>
<EuiFormRow
label="Source"
fullWidth
helpText="Put your source content here"
>
<EuiTextArea
fullWidth
placeholder="class HelloWorld {}"
value={this.state.content}
onChange={(e) => this.setState({content: e.target.value})}
/>
</EuiFormRow>
<EuiButton type="submit" size="s" fill onClick={() => this.highlight()}>
Highlight
</EuiButton>
</EuiForm>
<EuiSpacer size="xl"/>
<EuiPanel paddingSize="l" hasShadow>
{ this.state.html &&
<EuiCode dangerouslySetInnerHTML={{ __html: this.state.html }} />
}
</EuiPanel>
<EuiPanel paddingSize="l" hasShadow>
<EuiCodeBlock language="java">
{this.state.content}
</EuiCodeBlock>
</EuiPanel>
</div>
)
}
}
17 changes: 12 additions & 5 deletions kibana-extra/castro/public/components/main/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ import {
EuiDescriptionList,
EuiAccordion,
EuiCodeBlock,
EuiCode,
EuiSpacer
} from "@elastic/eui";

import {ICommit, IEntry} from '../../../common/proto'

import Code from './code'

interface MainProps {
title: String,
httpClient: any
Expand Down Expand Up @@ -60,8 +64,9 @@ export class Main extends React.Component<MainProps, MainState> {
description: data.message
}
];
let entries = data.entries || [];

this.setState({commitInfo, entries: data.entries || []});
this.setState({commitInfo, entries: entries});
});
}

Expand All @@ -88,6 +93,8 @@ export class Main extends React.Component<MainProps, MainState> {
style={{maxWidth: '800px'}}
/>
<EuiSpacer size="xl"/>
<Code httpClient={this.props.httpClient}/>
<EuiSpacer size="xl"/>
<EuiTitle>
<h2>Changed files</h2>
</EuiTitle>
Expand All @@ -99,10 +106,10 @@ export class Main extends React.Component<MainProps, MainState> {
key={"fid" + idx}
buttonContent={entry.path}
>
<EuiCodeBlock language="javascript">
{entry.blob}
</EuiCodeBlock>

{
entry.html &&
<EuiCode dangerouslySetInnerHTML={{ __html: entry.html }} />
}
</EuiAccordion>
)
}
Expand Down
66 changes: 66 additions & 0 deletions kibana-extra/castro/server/highlights.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
const Highlights = require('highlights');
const highlighter = new Highlights();
const Selector = require('first-mate-select-grammar');

highlighter.loadGrammarsSync();

const selector = Selector();

interface CodeLine extends Array<Token> {
}

interface Token {
value: string
scopes: string[]
range?: Range
}

interface Range {
start: number // start pos in line
end: number
pos?: number // position in file
}


export function tokenizeLines(filePath: string, fileContents: string): CodeLine[] {
const grammar = selector.selectGrammar(highlighter.registry, filePath, fileContents);
if (grammar) {
return grammar.tokenizeLines(fileContents);
} else {
return [];
}
}

export function computeRanges(lines: CodeLine[]) {
let pos = 0;
for (let line of lines) {
let start = 0;

for (let token of line) {
let len = token.value.length;
token.range = {
start,
end: start + len,
pos
};
start += len;
pos += len;
}
pos += 1; // line break
}
}

export function render(lines: CodeLine[]) : string{
let output = "<pre class='code'>";
for(let line of lines) {
output += "<div class='code-line'>";
for(let token of line){
let lastScope = token.scopes[token.scopes.length - 1];
const clazz = lastScope.replace(/\./g, " ");
output += `<span class="${clazz}">${highlighter.escapeString(token.value)}</span>`
}
output += "\n</div>";
}

return output + "</pre>"
}
32 changes: 28 additions & 4 deletions kibana-extra/castro/server/routes/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import {TreeEntry} from "nodegit";
import * as Hapi from 'hapi';
import {Commit} from '../../common/proto'

import {render, computeRanges, tokenizeLines} from '../highlights';


const Git = require("nodegit");
const Path = require("path");

Expand All @@ -22,11 +25,20 @@ async function getHeadCommit(): Promise<Commit> {
const walker = tree.walk(true);
walker.on("entry", async (entry: TreeEntry) => {
const blob = await entry.getBlob();
result.entries.push({
const isBinary = blob.isBinary() === 1;
let e = {
path: entry.path(),
isBinary: blob.isBinary() === 1,
blob: blob.isBinary() === 1 ? "binary" : blob.toString()
})
isBinary: isBinary,
blob: isBinary ? "binary" : blob.toString()
};
if(!isBinary) {
const lines = tokenizeLines(e.path, e.blob);
computeRanges(lines);
const result = render(lines);
e.html = result;
}

result.entries.push(e)
});
walker.start();
return await (new Promise<Commit>(function (resolve, reject) {
Expand All @@ -44,4 +56,16 @@ export default function (server: Hapi.Server) {
getHeadCommit().then((result: Commit) => reply(result))
}
});
server.route({
path: '/api/castro/highlight/{path}',
method: 'POST',
handler(req: Hapi.Request, reply: any) {
const { content }= req.payload;
const path = req.params.path;
const lines = tokenizeLines(path, content);
computeRanges(lines);
const result = render(lines);
reply(result)
}
})
}
Loading

0 comments on commit 05e826a

Please sign in to comment.