mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
* Updated commit * Update package.json * Update package.json Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
This commit is contained in:
parent
7d767cf0c9
commit
a09c7b72c7
@ -41,6 +41,7 @@
|
||||
"base64-stream": "^1.0.0",
|
||||
"clean-html": "^1.5.0",
|
||||
"compare-version": "^0.1.2",
|
||||
"countable": "^3.0.1",
|
||||
"diacritics": "^1.3.0",
|
||||
"diff-match-patch": "^1.0.4",
|
||||
"es6-promise-pool": "^2.5.0",
|
||||
@ -90,6 +91,7 @@
|
||||
"read-chunk": "^2.1.0",
|
||||
"redux": "^3.7.2",
|
||||
"relative": "^3.0.2",
|
||||
"remove-markdown": "^0.3.0",
|
||||
"request": "^2.88.0",
|
||||
"sax": "^1.2.4",
|
||||
"server-destroy": "^1.0.1",
|
||||
|
@ -85,4 +85,41 @@ describe('markdownUtils', function() {
|
||||
}
|
||||
}));
|
||||
|
||||
it('should remove Markdown syntax elements from the text', asyncTest(async () => {
|
||||
const inputStrings = [
|
||||
'', // Empty string
|
||||
'This is some plain text', // Plain text
|
||||
'## This is a header', // Header syntax
|
||||
'This is a text with **bold** and *italicized* text', // Text with annotations
|
||||
'This is a text with __bold__ and _italicized_ text', // Text with annotations alternate form
|
||||
'[link to google](https://www.google.com/)', // Link
|
||||
'> This is a blockquote\n And another line', // Blockquote
|
||||
'* List item\n* List item', // Unordered list
|
||||
'- List item\n- List item', // Unordered list
|
||||
'1. List item\n2. List item', // Ordered list
|
||||
'This is some `inline code`', // Inlined code
|
||||
];
|
||||
|
||||
const expectedOutputStrings = [
|
||||
'',
|
||||
'This is some plain text',
|
||||
'This is a header',
|
||||
'This is a text with bold and italicized text',
|
||||
'This is a text with bold and italicized text',
|
||||
'link to google',
|
||||
'This is a blockquote\n And another line',
|
||||
'List item\nList item',
|
||||
'List item\nList item',
|
||||
'List item\nList item',
|
||||
'This is some inline code',
|
||||
];
|
||||
|
||||
expect(inputStrings.length).toBe(expectedOutputStrings.length);
|
||||
|
||||
for (let i = 0; i < inputStrings.length; i++) {
|
||||
const outputString = markdownUtils.stripMarkdown(inputStrings[i]);
|
||||
expect(outputString).toBe(expectedOutputStrings[i]);
|
||||
}
|
||||
}));
|
||||
|
||||
});
|
||||
|
@ -3,7 +3,8 @@ import { useState, useEffect } from 'react';
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
const DialogButtonRow = require('./DialogButtonRow.min');
|
||||
const Countable = require('countable');
|
||||
const { stripMarkdown } = require('lib/markdownUtils');
|
||||
const { countElements } = require('lib/string-utils');
|
||||
|
||||
interface NoteContentPropertiesDialogProps {
|
||||
theme: number,
|
||||
@ -21,19 +22,25 @@ interface KeyToLabelMap {
|
||||
|
||||
export default function NoteContentPropertiesDialog(props:NoteContentPropertiesDialogProps) {
|
||||
const theme = themeStyle(props.theme);
|
||||
const textComps: JSX.Element[] = [];
|
||||
const tableBodyComps: JSX.Element[] = [];
|
||||
// For the source Markdown
|
||||
const [lines, setLines] = useState<number>(0);
|
||||
const [words, setWords] = useState<number>(0);
|
||||
const [characters, setCharacters] = useState<number>(0);
|
||||
const [charactersNoSpace, setCharactersNoSpace] = useState<number>(0);
|
||||
// For source with Markdown syntax stripped out
|
||||
const [strippedLines, setStrippedLines] = useState<number>(0);
|
||||
const [strippedWords, setStrippedWords] = useState<number>(0);
|
||||
const [strippedCharacters, setStrippedCharacters] = useState<number>(0);
|
||||
const [strippedCharactersNoSpace, setStrippedCharactersNoSpace] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
Countable.count(props.text, (counter: { words: number; all: number; characters: number; }) => {
|
||||
setWords(counter.words);
|
||||
setCharacters(counter.all);
|
||||
setCharactersNoSpace(counter.characters);
|
||||
});
|
||||
props.text === '' ? setLines(0) : setLines(props.text.split('\n').length);
|
||||
countElements(props.text, setWords, setCharacters, setCharactersNoSpace, setLines);
|
||||
}, [props.text]);
|
||||
|
||||
useEffect(() => {
|
||||
const strippedText: string = stripMarkdown(props.text);
|
||||
countElements(strippedText, setStrippedWords, setStrippedCharacters, setStrippedCharactersNoSpace, setStrippedLines);
|
||||
}, [props.text]);
|
||||
|
||||
const textProperties: TextPropertiesMap = {
|
||||
@ -43,6 +50,13 @@ export default function NoteContentPropertiesDialog(props:NoteContentPropertiesD
|
||||
charactersNoSpace: charactersNoSpace,
|
||||
};
|
||||
|
||||
const strippedTextProperties: TextPropertiesMap = {
|
||||
lines: strippedLines,
|
||||
words: strippedWords,
|
||||
characters: strippedCharacters,
|
||||
charactersNoSpace: strippedCharactersNoSpace,
|
||||
};
|
||||
|
||||
const keyToLabel: KeyToLabelMap = {
|
||||
words: _('Words'),
|
||||
characters: _('Characters'),
|
||||
@ -54,28 +68,62 @@ export default function NoteContentPropertiesDialog(props:NoteContentPropertiesD
|
||||
props.onClose();
|
||||
};
|
||||
|
||||
const createItemField = (key: string, value: number) => {
|
||||
const labelComp = <label style={Object.assign({}, theme.textStyle, theme.controlBoxLabel)}>{keyToLabel[key]}</label>;
|
||||
const controlComp = <div style={Object.assign({}, theme.textStyle, theme.controlBoxValue)}>{value}</div>;
|
||||
const labelCompStyle = {
|
||||
...theme.textStyle,
|
||||
fontWeight: 'bold',
|
||||
width: '10em',
|
||||
};
|
||||
|
||||
const controlCompStyle = {
|
||||
...theme.textStyle,
|
||||
textAlign: 'center',
|
||||
};
|
||||
|
||||
const createTableBodyRow = (key: string, value: number, strippedValue: number) => {
|
||||
const labelComp = <td style={labelCompStyle}>{keyToLabel[key]}</td>;
|
||||
const controlComp = <td style={controlCompStyle}>{value}</td>;
|
||||
const strippedControlComp = <td style={controlCompStyle}>{strippedValue}</td>;
|
||||
|
||||
return (
|
||||
<div key={key} style={theme.controlBox} className="note-text-property-box">{labelComp}{controlComp}</div>
|
||||
<tr key={key}>{labelComp}{controlComp}{strippedControlComp}</tr>
|
||||
);
|
||||
};
|
||||
|
||||
if (textProperties) {
|
||||
for (const key in textProperties) {
|
||||
if (!textProperties.hasOwnProperty(key)) continue;
|
||||
const comp = createItemField(key, textProperties[key]);
|
||||
textComps.push(comp);
|
||||
}
|
||||
const tableHeaderStyle = {
|
||||
...theme.textStyle,
|
||||
textAlign: 'center',
|
||||
};
|
||||
|
||||
const tableHeader = (
|
||||
<tr>
|
||||
<th style={tableHeaderStyle}></th>
|
||||
<th style={tableHeaderStyle}>{_('Editor')}</th>
|
||||
<th style={tableHeaderStyle}>{_('Viewer')}</th>
|
||||
</tr>
|
||||
);
|
||||
|
||||
for (const key in textProperties) {
|
||||
const comp = createTableBodyRow(key, textProperties[key], strippedTextProperties[key]);
|
||||
tableBodyComps.push(comp);
|
||||
}
|
||||
|
||||
const dialogBoxHeadingStyle = {
|
||||
...theme.dialogTitle,
|
||||
textAlign: 'center',
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={theme.dialogModalLayer}>
|
||||
<div style={theme.dialogBox}>
|
||||
<div style={theme.dialogTitle}>{_('Statistics')}</div>
|
||||
<div>{textComps}</div>
|
||||
<div style={dialogBoxHeadingStyle}>{_('Content properties')}</div>
|
||||
<table>
|
||||
<thead>
|
||||
{tableHeader}
|
||||
</thead>
|
||||
<tbody>
|
||||
{tableBodyComps}
|
||||
</tbody>
|
||||
</table>
|
||||
<DialogButtonRow theme={props.theme} onClick={buttonRow_click} okButtonShow={false} cancelButtonLabel={_('Close')}/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -164,6 +164,7 @@
|
||||
"readability-node": "^0.1.0",
|
||||
"redux": "^3.7.2",
|
||||
"relative": "^3.0.2",
|
||||
"remove-markdown": "^0.3.0",
|
||||
"reselect": "^4.0.0",
|
||||
"sax": "^1.2.4",
|
||||
"server-destroy": "^1.0.1",
|
||||
|
@ -2,6 +2,7 @@ const stringPadding = require('string-padding');
|
||||
const urlUtils = require('lib/urlUtils');
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const { setupLinkify } = require('lib/joplin-renderer');
|
||||
const removeMarkdown = require('remove-markdown');
|
||||
|
||||
const markdownUtils = {
|
||||
// Not really escaping because that's not supported by marked.js
|
||||
@ -101,6 +102,11 @@ const markdownUtils = {
|
||||
const title = lines[0].trim();
|
||||
return title.replace(filterRegex, '').replace(mdLinkRegex, '$1').replace(emptyMdLinkRegex, '$1').substring(0,80);
|
||||
},
|
||||
|
||||
stripMarkdown(text, options = { gfm: false }) {
|
||||
// Removes Markdown syntax elements from the given text
|
||||
return removeMarkdown(text, options);
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = markdownUtils;
|
||||
|
@ -1,4 +1,5 @@
|
||||
const stringUtilsCommon = require('./string-utils-common.js');
|
||||
const Countable = require('countable');
|
||||
|
||||
const defaultDiacriticsRemovalMap = [
|
||||
{ base: 'A', letters: /[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g },
|
||||
@ -285,4 +286,13 @@ function scriptType(s) {
|
||||
return 'en';
|
||||
}
|
||||
|
||||
module.exports = Object.assign({ removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString }, stringUtilsCommon);
|
||||
function countElements(text, wordSetter, characterSetter, characterNoSpaceSetter, lineSetter) {
|
||||
Countable.count(text, counter => {
|
||||
wordSetter(counter.words);
|
||||
characterSetter(counter.all);
|
||||
characterNoSpaceSetter(counter.characters);
|
||||
});
|
||||
text === '' ? lineSetter(0) : lineSetter(text.split('\n').length);
|
||||
}
|
||||
|
||||
module.exports = Object.assign({ removeDiacritics, substrWithEllipsis, nextWhitespaceIndex, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase, urlDecode, escapeHtml, surroundKeywords, scriptType, commandArgumentsToString, countElements }, stringUtilsCommon);
|
||||
|
Loading…
Reference in New Issue
Block a user