diff --git a/package.json b/package.json index c062d97..89865f4 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build": "tsc", "write-help-output": "echo \"$ embedme --help\" > readme/help-output.txt && node dist/embedme.js --help >> readme/help-output.txt", "start": "node dist/embedme.js README.md", - "test:write": "node dist/embedme.js test/fixture.md && yarn prettier:write", + "test:write": "node dist/embedme.js test/fixture-source.md --stdout > test/fixture.md && node dist/embedme.js test/fixture.md --check && yarn prettier:write", "test:check": "! git status | grep test/fixture.md || (echo 'You must commit build and commit changes to test/fixture.md!' && exit 1)", "test": "yarn test:write && yarn test:check", "commit": "git add . && git-cz", diff --git a/src/embedme.lib.ts b/src/embedme.lib.ts index abc2f12..e50c365 100644 --- a/src/embedme.lib.ts +++ b/src/embedme.lib.ts @@ -141,7 +141,7 @@ const filetypeCommentReaders: Record = return match[1]; }, [CommentFamily.HASH]: leadingSymbol('#'), - [CommentFamily.SINGLE_QUOTE]: leadingSymbol('//'), + [CommentFamily.SINGLE_QUOTE]: leadingSymbol(`'`), [CommentFamily.DOUBLE_PERCENT]: leadingSymbol('%%'), }; @@ -189,50 +189,55 @@ function getReplacement( logMethod(logPrefix, ...messages); }; - if (!codeExtension) { - log({ returnSnippet: substr }, chalk.blue(`No code extension detected, skipping code block...`)); - return substr; - } - - if (!firstLine && !commentEmbedOverrideFilepath) { - log({ returnSnippet: substr }, chalk.blue(`Code block is empty & no preceding embedme comment, skipping...`)); - return substr; - } - if (ignoreNext) { log({ returnSnippet: substr }, chalk.blue(`"Ignore next" comment detected, skipping code block...`)); return substr; } - const supportedFileTypes: SupportedFileType[] = Object.values(SupportedFileType).filter(x => typeof x === 'string'); + let commentedFilename: string | null; + if (commentEmbedOverrideFilepath) { + commentedFilename = commentEmbedOverrideFilepath; + } else { + if (!codeExtension) { + log({ returnSnippet: substr }, chalk.blue(`No code extension detected, skipping code block...`)); + return substr; + } - if (supportedFileTypes.indexOf(codeExtension) < 0) { - log( - { returnSnippet: substr }, - chalk.yellow( - `Unsupported file extension [${codeExtension}], supported extensions are ${supportedFileTypes.join( - ', ', - )}, skipping code block`, - ), - ); - return substr; - } + if (!firstLine) { + log({ returnSnippet: substr }, chalk.blue(`Code block is empty & no preceding embedme comment, skipping...`)); + return substr; + } - const languageFamily: CommentFamily | null = lookupLanguageCommentFamily(codeExtension); + const supportedFileTypes: SupportedFileType[] = Object.values(SupportedFileType).filter(x => typeof x === 'string'); + + if (supportedFileTypes.indexOf(codeExtension) < 0) { + log( + { returnSnippet: substr }, + chalk.yellow( + `Unsupported file extension [${codeExtension}], supported extensions are ${supportedFileTypes.join( + ', ', + )}, skipping code block`, + ), + ); + return substr; + } - if (languageFamily == null) { - log( - { returnSnippet: substr }, - chalk.red( - `File extension ${chalk.underline( - codeExtension, - )} marked as supported, but comment family could not be determined. Please report this issue.`, - ), - ); - return substr; - } + const languageFamily: CommentFamily | null = lookupLanguageCommentFamily(codeExtension); + + if (languageFamily == null) { + log( + { returnSnippet: substr }, + chalk.red( + `File extension ${chalk.underline( + codeExtension, + )} marked as supported, but comment family could not be determined. Please report this issue.`, + ), + ); + return substr; + } - const commentedFilename = commentEmbedOverrideFilepath || filetypeCommentReaders[languageFamily](firstLine); + commentedFilename = filetypeCommentReaders[languageFamily](firstLine); + } if (!commentedFilename) { log( @@ -245,7 +250,7 @@ function getReplacement( const matches = commentedFilename.match(/\s?(\S+?)((#L(\d+)-L(\d+))|$)/m); if (!matches) { - log({ returnSnippet: substr }, chalk.gray(`No file found in first comment block`)); + log({ returnSnippet: substr }, chalk.gray(`No file found in embed line`)); return substr; } @@ -341,7 +346,7 @@ function getReplacement( return substr; } - const chalkColour = options.verify ? 'red' : 'green'; + const chalkColour = options.verify ? 'yellow' : 'green'; log( { returnSnippet: replacement }, @@ -378,7 +383,7 @@ export function embedme(sourceText: string, inputFilePath: string, options: Embe const [codeFence, leadingSpaces] = result; const start = sourceText.substring(previousEnd, result.index); - const extensionMatch = codeFence.match(/```(\S*)/); + const extensionMatch = codeFence.match(/```(.*)/); const codeExtension = extensionMatch ? extensionMatch[1] : null; const splitFence = codeFence.split('\n'); diff --git a/test/fixture-source.md b/test/fixture-source.md new file mode 100644 index 0000000..841358c --- /dev/null +++ b/test/fixture-source.md @@ -0,0 +1,292 @@ +# File types + +Plain Text + +```txt +// sample.txt +``` + +Typescript + +```ts +// sample.ts +``` + +Javascript + +```js +// sample.js +``` + +HTML + +```html + +``` + +Python + +```py +# sample.py +``` + +Rust + +```rust +// sample.rs + +``` + +C++ + +```cpp +// sample.cpp +``` + +C + +```c +// sample.c +``` + +Java + +```java +// sample.java +``` + +Golang + +```go +// sample.go +``` + +Bash + +```sh +# sample.sh +``` + +Shell + +```sh +# sample.sh +``` + +Objective C + +```objectivec +// sample.m +``` + +SCSS + +```scss +// sample.scss +``` + +PHP + +```php +// sample.php +``` + +C# + +```cs +// sample.cs +``` + +Swift + +```swift +// sample.swift +``` + +XML + +```xml + +``` + +Yaml + +```yaml +# sample.yaml +``` + +JSON + + + +```json + +``` + +JSON5 + +```json5 +// sample.json5 +``` + +Ruby + +```rb +# sample.rb +``` + +Crystal + +```cr +# sample.cr +``` + +Kotlin + +```kotlin +// sample.kt +``` + +Scala + +```scala +// sample.scala +``` + +Plant UML + +```puml +' sample.puml +``` + +Mermaid + +```mermaid +%% sample.mermaid +``` + +Protobuf + +```proto +// sample.proto +``` + +CMake + +```cmake +# sample.cmake +``` + +## Extension-less selection + +```sh +# sample +``` + +## Line selection + +```cs +// sample.cs#L6-L13 +``` + +## Indented selection + + ```ts + // sample.ts + ``` + +## Embedme Ignore + + + +```ts +// sample.ts +``` + +## Embedme Ignore alt syntax + + + +```ts +// sample.ts +``` + +## Embed with comment + + + +```ts +``` + +### Embed with comment and unknown file type + + + +```{.json caption="Some JSON file"} + +``` + +## Errors + +### Empty block + +```ts +``` + +### No file handler + +```binary +01001000 01100101 01101100 01101100 01101111 00100000 01010111 01101111 01110010 01101100 01100100 +``` + +### No file extension + +``` +Ignored block +``` + +### Bad file format + +```ts +// Not a file +``` + +### Also bad file format + +```ts +// also-not-a-file +``` + +### Missing file + +```txt +// this-file-does-not-exist.txt +``` + +### Contains Codefence + +```md + +``` + +### Contains Codefence, but not the embedded lines + +```md + + +# This markdown document + +## Contains a codefence +``` + +### malformed line numbering + +```ts +// sample.ts#L1-2 +``` + +### missing comment on language embed with no comment support + +```json + +``` diff --git a/test/fixture.md b/test/fixture.md index a08a472..148c4a0 100644 --- a/test/fixture.md +++ b/test/fixture.md @@ -257,7 +257,7 @@ puts 'Hello, world!' ``` -Ruby +Crystal ```cr # sample.cr @@ -411,6 +411,17 @@ export function hello(): string { } ``` +### Embed with comment and unknown file type + + + +```{.json caption="Some JSON file"} +{ + "hello": "world" +} + +``` + ## Errors ### Empty block