mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
added markdown formatter
This commit is contained in:
parent
8f9c61e1f6
commit
0666237586
7 changed files with 111 additions and 126 deletions
|
@ -9,7 +9,7 @@ const CommentTextBlock: FC<IProps> = ({ block }) => {
|
|||
<div
|
||||
className={styles.text}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `<p>${block.content}</p>`,
|
||||
__html: block.content,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -8,6 +8,17 @@ import Axios from 'axios';
|
|||
import { PRESETS } from '~/constants/urls';
|
||||
import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/constants/comment';
|
||||
import format from 'date-fns/format';
|
||||
import { pipe } from 'ramda';
|
||||
import {
|
||||
formatDash,
|
||||
formatExclamations,
|
||||
formatMarkdown,
|
||||
formatTextClickableUsernames,
|
||||
formatTextComments,
|
||||
formatTextSanitizeTags,
|
||||
formatTextSanitizeYoutube,
|
||||
formatTextTodos,
|
||||
} from '~/utils/formatText';
|
||||
|
||||
export const getStyle = (oElm: any, strCssRule: string) => {
|
||||
if (document.defaultView && document.defaultView.getComputedStyle) {
|
||||
|
@ -82,50 +93,18 @@ export const getURL = (file: Partial<IFile>, size?: typeof PRESETS[keyof typeof
|
|||
return file?.url ? getURLFromString(file.url, size) : null;
|
||||
};
|
||||
|
||||
export const formatText = (text: string): string =>
|
||||
!text
|
||||
? ''
|
||||
: text
|
||||
.replace(
|
||||
/(https?:\/\/(www\.)?(youtube\.com|youtu\.be)\/(watch)?(\?v=)?[\w\-\&\=]+)/gim,
|
||||
'\n$1\n'
|
||||
)
|
||||
.replace(/\n{1,}/gim, '\n')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(
|
||||
/~([\wа-яА-Я-]+)/giu,
|
||||
'<span class="username" onClick="window.postMessage({ type: \'username\', username: \'$1\'});">~$1</span>'
|
||||
)
|
||||
.replace(/:\/\//gim, ':|--|')
|
||||
.replace(/(\/\/[^\n]+)/gim, '<span class="grey">$1</span>')
|
||||
.replace(/\/\/\s*(todo|туду):?\s*([^\n]+)/gim, '// <span class="todo">$1</span> $2')
|
||||
.replace(
|
||||
/\/\/\s*(done|сделано|сделал|готово|fixed|пофикшено|фиксед):?\s*([^\n]+)/gim,
|
||||
'// <span class="done">$1</span> $2'
|
||||
)
|
||||
.replace(/(\*\*[\s\S]*?\*\*)/gim, '<b class="bold white">$1</b>')
|
||||
.replace(/(\_\_[\s\S]*?\_\_)/gim, '<i>$1</i>')
|
||||
.replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '<span class="green">$1</span>')
|
||||
.replace(/(\/\*[\s\S]*?\*\/)/gim, '<span class="grey">$1</span>')
|
||||
.replace(/([=|-]{5,})/gim, '<hr />')
|
||||
.replace(/:\|--\|/gim, '://')
|
||||
.replace(
|
||||
/(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/gi,
|
||||
'<a href="$1" target="blank" rel="nofollow">$1</a>'
|
||||
)
|
||||
.replace(' -- ', ' — ')
|
||||
.split('\n')
|
||||
.filter(el => el.trim().length)
|
||||
.join('\n');
|
||||
export const formatText = pipe(
|
||||
formatTextSanitizeYoutube,
|
||||
formatTextSanitizeTags,
|
||||
formatTextClickableUsernames,
|
||||
formatTextComments,
|
||||
formatTextTodos,
|
||||
formatExclamations,
|
||||
formatDash,
|
||||
formatMarkdown
|
||||
);
|
||||
|
||||
export const formatTextParagraphs = (text: string): string =>
|
||||
(text &&
|
||||
formatText(text)
|
||||
.split('\n')
|
||||
.map(str => `<p>${str}</p>`)
|
||||
.join('\n')) ||
|
||||
null;
|
||||
export const formatTextParagraphs = (text: string): string => (text && formatText(text)) || null;
|
||||
|
||||
export const findBlockType = (line: string): ValueOf<typeof COMMENT_BLOCK_TYPES> => {
|
||||
const match = Object.values(COMMENT_BLOCK_DETECTORS).find(detector => line.match(detector.test));
|
||||
|
|
71
src/utils/formatText.ts
Normal file
71
src/utils/formatText.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
import marked from 'marked';
|
||||
|
||||
/**
|
||||
* Cleans youtube urls
|
||||
*/
|
||||
export const formatTextSanitizeYoutube = (text: string): string =>
|
||||
text.replace(
|
||||
/(https?:\/\/(www\.)?(youtube\.com|youtu\.be)\/(watch)?(\?v=)?[\w\-\&\=]+)/gim,
|
||||
'\n$1\n'
|
||||
);
|
||||
|
||||
/**
|
||||
* Removes HTML tags
|
||||
*/
|
||||
export const formatTextSanitizeTags = (text: string): string =>
|
||||
text.replace(/</g, '<').replace(/>/g, '>');
|
||||
|
||||
/**
|
||||
* Returns clickable usernames
|
||||
*/
|
||||
export const formatTextClickableUsernames = (text: string): string =>
|
||||
text.replace(
|
||||
/~([\wа-яА-Я-]+)/giu,
|
||||
'<span class="username" onClick="window.postMessage({ type: \'username\', username: \'$1\'});">~$1</span>'
|
||||
);
|
||||
|
||||
/**
|
||||
* Makes gray comments
|
||||
*/
|
||||
export const formatTextComments = (text: string): string =>
|
||||
text
|
||||
.replace(/:\/\//gim, ':|--|')
|
||||
.replace(/(\/\/[^\n]+)/gim, '<span class="grey">$1</span>')
|
||||
.replace(/(\/\*[\s\S]*?\*\/)/gim, '<span class="grey">$1</span>')
|
||||
.replace(/:\|--\|/gim, '://');
|
||||
|
||||
/**
|
||||
* Highlights todos
|
||||
*/
|
||||
export const formatTextTodos = (text: string): string =>
|
||||
text
|
||||
.replace(/\/\/\s*(todo|туду):?\s*([^\n]+)/gim, '// <span class="todo">$1</span> $2')
|
||||
.replace(
|
||||
/\/\/\s*(done|сделано|сделал|готово|fixed|пофикшено|фиксед):?\s*([^\n]+)/gim,
|
||||
'// <span class="done">$1</span> $2'
|
||||
);
|
||||
|
||||
/**
|
||||
* Formats !!exclamation messages with green color
|
||||
*/
|
||||
export const formatExclamations = (text: string): string =>
|
||||
text.replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '<span class="green">$1</span>');
|
||||
|
||||
/**
|
||||
* Formats links
|
||||
*/
|
||||
export const formatLinks = (text: string): string =>
|
||||
text.replace(
|
||||
/(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/gi,
|
||||
'<a href="$1" target="blank" rel="nofollow">$1</a>'
|
||||
);
|
||||
|
||||
/**
|
||||
* Replaces -- with dash
|
||||
*/
|
||||
export const formatDash = (text: string): string => text.replace(' -- ', ' — ');
|
||||
|
||||
/**
|
||||
* Formats with markdown
|
||||
*/
|
||||
export const formatMarkdown = (text: string): string => marked(text);
|
|
@ -5,11 +5,5 @@ type Handlers<State, Types extends string, Actions extends Action<Types>> = {
|
|||
readonly [Type in Types]: (state: State, action: Actions) => State;
|
||||
};
|
||||
|
||||
// export const createReducer = <State, Types extends string, Actions extends Action<Types>>(
|
||||
// initialState: State,
|
||||
// handlers: Handlers<State, Types, Actions>,
|
||||
// ) => (state = initialState, action: Actions) =>
|
||||
// handlers.hasOwnProperty(action.type) ? handlers[action.type as Types](state, action) : state;
|
||||
|
||||
export const createReducer = (initialState, handlers) => (state = initialState, action) =>
|
||||
handlers.hasOwnProperty(action.type) ? handlers[action.type](state, action) : state;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue