Skip to content

Commit

Permalink
0.9.2 (#334)
Browse files Browse the repository at this point in the history
* fix: Fixed a bug of importing image

* feat: Ready to release 0.9.2

* refactor: Refactored the code a bit

* feat: Added ID button

* feat: Supported to import section of markdown by header id

* ci: Fixed a ci build

* feat: Exported HeadingIdGenerator
  • Loading branch information
shd101wyy authored Oct 15, 2023
1 parent 64eec7b commit dfffe53
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 44 deletions.
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,33 @@ Please visit https://github.com/shd101wyy/vscode-markdown-preview-enhanced/relea

## [Unreleased]

## [0.9.2] - 2023-10-15

### New features

- Added `ID` button to copy the element id to clipboard:

![Screenshot from 2023-10-15 15-34-27](https://github.com/shd101wyy/crossnote/assets/1908863/ede91390-3cca-4b83-8e30-33027bf0a363)

- Supported to import section of markdown by header id:

```markdown
@import "test.md#header-id"

or

![](test.md#header-id)

or

![[test#header-id]]
```

### Bug fixes

- URL fragments on image links do not load: https://github.com/shd101wyy/vscode-markdown-preview-enhanced/issues/1837
- Supported matplotlib-type preview for other Python tools like `pipenv`: https://github.com/shd101wyy/crossnote/issues/332

## [0.9.1] - 2023-10-14

### Buf fixes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "crossnote",
"version": "0.9.1",
"version": "0.9.2",
"description": "A powerful markdown notebook tool",
"keywords": [
"markdown"
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import HeadingIdGenerator from './markdown-engine/heading-id-generator';
import {
addFileProtocol,
getCrossnoteBuildDirectory,
Expand All @@ -23,3 +24,4 @@ export {
loadConfigsInDirectory,
wrapNodeFSAsApi,
} from './notebook/config-helper';
export { HeadingIdGenerator };
4 changes: 4 additions & 0 deletions src/markdown-engine/toc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export interface HeadingData {
level: number;
offset?: number;
id?: string;
/**
* 1-based line number
*/
lineNo?: number;
}

export function toc(headings: HeadingData[], opt: TocOption) {
Expand Down
120 changes: 86 additions & 34 deletions src/markdown-engine/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface TransformMarkdownOptions {
forMarkdownExport?: boolean;
protocolsWhiteListRegExp: RegExp | null;
notSourceFile?: boolean;
fileHash?: string;
imageDirectoryPath?: string;
headingIdGenerator?: HeadingIdGenerator;
notebook: Notebook;
Expand Down Expand Up @@ -243,6 +244,7 @@ export async function transformMarkdown(
headingIdGenerator = new HeadingIdGenerator(),
notebook,
forJest = false,
fileHash,
}: TransformMarkdownOptions,
): Promise<TransformMarkdownOutput> {
// Replace CRLF with LF
Expand Down Expand Up @@ -497,7 +499,7 @@ export async function transformMarkdown(
}

if (!ignore) {
headings.push({ content: heading, level, id });
headings.push({ content: heading, level, id, lineNo: lineNo + 1 });
}
// console.log(`heading: |${heading}|`);

Expand Down Expand Up @@ -625,7 +627,7 @@ export async function transformMarkdown(
}
}

let absoluteFilePath;
let absoluteFilePath: string;
if (
protocolsWhiteListRegExp &&
filePath.match(protocolsWhiteListRegExp)
Expand All @@ -636,13 +638,46 @@ export async function transformMarkdown(
} else {
absoluteFilePath = path.resolve(fileDirectoryPath, filePath);
}
let fileHash = '';
const hashIndex = absoluteFilePath.lastIndexOf('#');
if (hashIndex > 0) {
fileHash = absoluteFilePath.substring(hashIndex);
absoluteFilePath = absoluteFilePath.substring(0, hashIndex);
}

const extname = path.extname(filePath).toLocaleLowerCase();
const extname = path.extname(absoluteFilePath).toLocaleLowerCase();
let output = '';
if (
['.jpeg', '.jpg', '.gif', '.png', '.apng', '.svg', '.bmp'].indexOf(
extname,
) >= 0
if (filePath === '[TOC]') {
if (!config) {
config = {
// same case as in normalized attributes
['depth_from']: 1,
['depth_to']: 6,
['ordered_list']: true,
};
}
config['cmd'] = 'toc';
config['hide'] = true;
config['run_on_save'] = true;
config['modify_source'] = true;
if (!notSourceFile) {
// mark code_chunk_offset
config['code_chunk_offset'] = codeChunkOffset;
codeChunkOffset++;
}

const output2 = `\`\`\`text ${stringifyBlockAttributes(
config,
)} \n\`\`\` `;
i = end + 1;
lineNo = lineNo + 1;
outputString = outputString + output2;
continue;
}
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types#common_image_file_types
else if (
extname.match(/^\.(apng|avif|gif|jpeg|jpg|png|svg|bmp|webp)/) ||
extname === '' // NOTE: For example, for github image like: ![Screenshot from 2023-10-15 15-34-27](https://github.com/shd101wyy/crossnote/assets/1908863/ede91390-3cca-4b83-8e30-33027bf0a363)
) {
if (importMatch || wikilinkImportMatch) {
// image
Expand Down Expand Up @@ -708,32 +743,6 @@ export async function transformMarkdown(
lineNo = lineNo + 1;
outputString = outputString + output + '\n';
continue;
} else if (filePath === '[TOC]') {
if (!config) {
config = {
// same case as in normalized attributes
['depth_from']: 1,
['depth_to']: 6,
['ordered_list']: true,
};
}
config['cmd'] = 'toc';
config['hide'] = true;
config['run_on_save'] = true;
config['modify_source'] = true;
if (!notSourceFile) {
// mark code_chunk_offset
config['code_chunk_offset'] = codeChunkOffset;
codeChunkOffset++;
}

const output2 = `\`\`\`text ${stringifyBlockAttributes(
config,
)} \n\`\`\` `;
i = end + 1;
lineNo = lineNo + 1;
outputString = outputString + output2;
continue;
} else {
try {
let fileContent = await loadFile(
Expand Down Expand Up @@ -785,7 +794,7 @@ export async function transformMarkdown(
config,
)} \n${fileContent}\n\`\`\` `;
} else if (
notebook.config.markdownFileExtensions.indexOf(extname) >= 0
notebook.config.markdownFileExtensions.includes(extname)
) {
if (notebook.config.parserConfig.onWillTransformMarkdown) {
fileContent =
Expand Down Expand Up @@ -814,6 +823,7 @@ export async function transformMarkdown(
imageDirectoryPath,
notebook,
headingIdGenerator,
fileHash,
}));

if (notebook.config.parserConfig) {
Expand Down Expand Up @@ -1051,6 +1061,48 @@ export async function transformMarkdown(
outputString = '\n'.repeat(newLines + 1) + outputString;
}

if (fileHash) {
const targetId = fileHash.slice(1);
if (targetId) {
const targetHeadingIndex = headings.findIndex(
(heading) => heading.id === targetId,
);
if (targetHeadingIndex >= 0) {
const startHeading = headings[targetHeadingIndex];
const startHeadingIndex = targetHeadingIndex;
const { level } = startHeading;

// Find the endHeading which has the same or lower level as startHeading
let endHeadingIndex = startHeadingIndex + 1;
let endHeading: HeadingData | null = null;
while (endHeadingIndex < headings.length) {
const heading = headings[endHeadingIndex];
if (heading.level <= level) {
endHeading = heading;
break;
}
endHeadingIndex++;
}

const startLineNo = startHeading.lineNo as number;
if (endHeading) {
headings = headings.slice(startHeadingIndex, endHeadingIndex);
const endLineNo = endHeading.lineNo as number;
outputString = outputString
.split('\n')
.slice(startLineNo - 1, endLineNo - 1)
.join('\n');
} else {
headings = headings.slice(startHeadingIndex);
outputString = outputString
.split('\n')
.slice(startLineNo - 1)
.join('\n');
}
}
}
}

// Done
return {
outputString,
Expand Down
5 changes: 4 additions & 1 deletion src/render-enhancers/fenced-code-chunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,10 @@ export async function runCodeChunk(
// set output format for a few special cases
if (cmd.match(/(la)?tex/) || cmd === 'pdflatex') {
outputFormat = 'markdown';
} else if (normalizedAttributes['matplotlib'] || normalizedAttributes['mpl']) {
} else if (
normalizedAttributes['matplotlib'] ||
normalizedAttributes['mpl']
) {
outputFormat = 'markdown';
} else if (codeChunkData.normalizedInfo.attributes['output']) {
outputFormat = codeChunkData.normalizedInfo.attributes['output'];
Expand Down
57 changes: 49 additions & 8 deletions src/webview/components/FloatingActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
mdiClose,
mdiContentCopy,
mdiDotsHorizontal,
mdiIdentifier,
mdiPencil,
} from '@mdi/js';
import Icon from '@mdi/react';
Expand All @@ -19,7 +20,10 @@ export default function FloatingActions() {
setHighlightElementBeingEdited,
} = PreviewContainer.useContainer();
const [showMoreActions, setShowMoreActions] = useState(false);
const [showCopiedTooltip, setShowCopiedTooltip] = useState<
const [showCopiedMarkdownTooltip, setShowCopiedMarkdownTooltip] = useState<
string | undefined
>(undefined);
const [showCopiedIdTooltip, setShowCopiedIdTooltip] = useState<
string | undefined
>(undefined);

Expand All @@ -35,10 +39,11 @@ export default function FloatingActions() {
highlightLineElements.forEach((element) => {
element.classList.remove('highlight-active');
});
setShowCopiedTooltip(undefined);
setShowCopiedMarkdownTooltip(undefined);
setShowCopiedIdTooltip(undefined);
}, []);

const copyToClipboard = useCallback(() => {
const copyMarkdownToClipboard = useCallback(() => {
if (!highlightElement) {
return;
}
Expand All @@ -61,13 +66,32 @@ export default function FloatingActions() {
document.execCommand('copy');
document.body.removeChild(textArea);

setShowCopiedTooltip(`Markdown copied!`);
setShowCopiedMarkdownTooltip(`Markdown copied!`);

setTimeout(() => {
setShowCopiedTooltip(undefined);
setShowCopiedMarkdownTooltip(undefined);
}, 1000);
}, [highlightElement, getHighlightElementLineRange, markdown]);

const copyIdToClipboard = useCallback(() => {
if (!highlightElement || !highlightElement.id) {
return;
}

const textArea = document.createElement('textarea');
textArea.value = highlightElement.id;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);

setShowCopiedIdTooltip(`"${highlightElement.id}" copied!`);

setTimeout(() => {
setShowCopiedIdTooltip(undefined);
}, 1000);
}, [highlightElement]);

useEffect(() => {
if (highlightElement && showMoreActions) {
document.body.classList.add('floating-action-open');
Expand Down Expand Up @@ -111,17 +135,34 @@ export default function FloatingActions() {
<div className="flex flex-row items-center">
{showMoreActions && (
<>
{highlightElement.id && (
<div
className={classNames(
'ml-1 flex',
showCopiedIdTooltip ? 'tooltip tooltip-open' : '',
)}
data-tip={showCopiedIdTooltip}
>
<button
className="btn btn-primary btn-circle btn-xs"
title={highlightElement.id}
onClick={copyIdToClipboard}
>
<Icon path={mdiIdentifier} size={0.8}></Icon>
</button>
</div>
)}
<div
className={classNames(
'ml-1 flex',
showCopiedTooltip ? 'tooltip tooltip-open' : '',
showCopiedMarkdownTooltip ? 'tooltip tooltip-open' : '',
)}
data-tip={showCopiedTooltip}
data-tip={showCopiedMarkdownTooltip}
>
<button
className="btn btn-primary btn-circle btn-xs"
title={'Copy the part of markdown'}
onClick={copyToClipboard}
onClick={copyMarkdownToClipboard}
>
<Icon path={mdiContentCopy} size={0.6}></Icon>
</button>
Expand Down

0 comments on commit dfffe53

Please sign in to comment.