-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathindex.js
147 lines (123 loc) · 4.35 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
const fs = require( 'fs-extra' );
const path = require( 'path' );
const chalk = require( 'chalk' );
const _ = require( 'lodash' );
const pretty = require( 'pretty' );
// library functions
const { getSvgDimensions } = require( './lib/util' );
const { codeToSvg, createFinalSVG, svgToImage, getOsxWindowSvg, getExecutionResultSVG } = require( './lib/functions' );
const { IMAGE_FORMATS, LANGUAGES, THEMES } = require( './lib/constants' );
// current working directory
const CWD = process.cwd();
/**
* @desc Return image buffer or write it to a file.
* @param {*} path - output file path
* @param {*} buffer - image buffer
*/
const returnBufferOrWrite = ( path, buffer ) => {
if( undefined !== path ) {
return fs.writeFile( path, buffer );
} else {
return buffer;
}
}
/**
* @desc Process final SVG image
* @param { string } path - output file path
* @param { string } svg - final SVG image string
* @param { string } format - output image format
* @param { number } scale - DPI scale factor
*/
const processFinalSvg = async ( { path, svg, format, scale } ) => {
// override JPG alias
format = _.toLower( format );
format = ( format === IMAGE_FORMATS.JPG ) ? IMAGE_FORMATS.JPEG : format;
// return SVG image or convert to portable image formats
switch( format ) {
// return SVG image
case IMAGE_FORMATS.SVG: {
return returnBufferOrWrite( path, Buffer.from( pretty( svg, { ocd: true } ), 'utf-8' ) );
}
// convert SVG to portable image formats
case IMAGE_FORMATS.JPEG:
case IMAGE_FORMATS.PNG: {
const buffer = await svgToImage( { svg, format, scale } );
return returnBufferOrWrite( path, buffer );
}
// show error if image format is invalid
default: {
console.log( chalk.red( `${ chalk.bold( format ) } is invalid image format. Valid formats are ${ _.join( _.values( IMAGE_FORMATS ), ', ' ) }.` ) );
process.exit( 0 );
}
}
};
/**
* @desc Converts a string (code) to an image with syntax highlighting
*/
const convert = async ( {
inputFile,
outputFile,
language = LANGUAGES.DART,
theme = THEMES.FIREWATCH,
format = IMAGE_FORMATS.PNG,
ignoreLineNumbers = false,
scale = 2,
hasFrame = true,
frameTitle = 'Code Snippet',
execute = null,
displayCommand = null,
} ) => {
// absolute paths
const inputFilePath = path.resolve( CWD, inputFile );
const outputFilePath = _.isEmpty( outputFile ) ? undefined : path.resolve( CWD, outputFile );
// read input file in text format
const code = fs.readFileSync( inputFilePath, { encoding: 'utf-8' } );
/*********************/
// header, body and footer SVG images to construct final image
const svgImages = {
// OSX window frame
header: {
svg: undefined,
dimensions: undefined
},
// actual code
body: {
svg: undefined,
dimensions: undefined
},
// terminal result
footer: {
svg: undefined,
dimensions: undefined
},
};
// create SVG image from code with syntax highlighting
svgImages.body.svg = codeToSvg( { code, language, theme, padding: '20,20', scale, ignoreLineNumbers } );
svgImages.body.dimensions = getSvgDimensions( svgImages.body.svg );
// create SVG image for OSX window frame
if( hasFrame ) {
svgImages.header.svg = getOsxWindowSvg( svgImages.body.dimensions.width, frameTitle );
svgImages.header.dimensions = getSvgDimensions( svgImages.header.svg );
}
// execute code file
if( execute ) {
svgImages.footer.svg = await getExecutionResultSVG( { inputFilePath, execute, displayCommand, theme, scale, width: svgImages.body.dimensions.width } );
svgImages.footer.dimensions = getSvgDimensions( svgImages.footer.svg );
}
// create final SVG by merging header, body and footer
const finalSVG = createFinalSVG( {
header: svgImages.header.svg,
body: svgImages.body.svg,
footer: svgImages.footer.svg,
cornerRadius: 5
} );
// process SVG image
return await processFinalSvg( { path: outputFilePath, svg: finalSVG, format, scale } );
};
/******************************/
module.exports = {
convert,
IMAGE_FORMATS,
LANGUAGES,
THEMES
};