난중일기/Front

Remirror Custom Extension 만들기

모집사 2024. 1. 11. 21:45
728x90
반응형

마크다운 문법에서 _문자_, *문자*가 있으면 자동으로 가운데 문자를 이탤릭체로 변경해준다.

그치만 우리는 snake case를 즐겨 쓰는 IT인들... 

에디터에 필드명을 쓸 때마다 언더바가 사라지고, 자동으로 이태릭 체가 되어버리는 열받는현상이 계속해서 발생해버리는 것이다.

그래서 이런 현상을 수정하기 위해 삽질을 해 보았다.

 

내가 작업한 서비스에서는 에디터에 Remirror 라이브러리를 사용했다. 간략하게 설명하자면 Remirror는 ProseMirror를 리액트에서 쉽게 사용할 수 있게 해주는 라이브러리이다. (문서 참고 https://remirror.io/docs)

 

 

 

우선 기본적인 Remirror Extension 사용법은 아래와 같다.

 

1. Remirror 패키지 설치

npm add remirror @remirror/react @remirror/pm

 

2. Extension을 사용하고자 하는 페이지에 Remirror Manager를 만든다.

ItalicExtension만 사용하고자 할 때는 아래와 같이 작성한다.

import { ItalicExtension } from 'remirror/extensions';
import { useRemirror } from '@remirror/react';

const { manager } = useRemirror({
  extensions: () => [new ItalicExtension()],
});

 

이탤릭 이외에도 우리가 에디터에서 볼 수 있는 볼드체, 테이블, 인용 구문 처리 등 여러가지 Extension을 지원하고 있다.

ItalicExtension은 별도로 옵션이 없지만, CodeBlockExtension같은 경우에는 supportedLanguages, defaultLanguage, toggleName등 여러가지 옵션을 설정할 수 있다.

import { ItalicExtension, CodeBlockExtension } from 'remirror/extensions';
import { useRemirror } from '@remirror/react';

const { manager } = useRemirror({
  extensions: () => [new ItalicExtension(), new CodeBlockExtension({supportedLanguages: [typescript, jsx]})],
});

 

3. 작성한 Remirror Manager를 렌더링해서 사용한다.

예를들어 Editor라는 컴포넌트를 만든다면, 아래와 같이 작성하면 된다.

export const Editor = () => {
  return (
    <div className='remirror-theme'>
      <Remirror manager={manager} initialContent={state} />
    </div>
  );
};

 

 

 

 

여기까지는 기본적인 사용법이었고,

내가 이번에 작업한 내용은 ItalicExtension에서 마크다운 문법을 _를 제외하고, *만 처리하도록 customExtension으로 변경한 내용이다.

 

우선 ItalicExtension이 어떻게 동작하는지 보기 위해 Remirror 코드를 확인했다.

createInputRules라는 메서드 내에 작성해놓은 룰을 기반으로, 정규식 룰에 맞으면 createMarkSpec에 작성된 내용에 따라 스타일을 부여한다.

 

기존 코드에는 정규표현식이 아래 두개로, *문자*, _문자_ 해당 룰에 따라 안에 있는 문자에 italic속성을 부여하고 있었다.

/(?:^|[^*])\*([^*]+)\*$/
/(?:^|[^_])_([^_]+)_$/

 

그래서 내가 수정한 내용은... CustonItalicExtension class를 새로 만들어서, ItalicExtension이 가지고 있는 name, createTags, createMarkSpec같은 함수들을 재작성 해주었다.

 

regExp도 *문자*만 인식할 수 있도록 /(?:^|[^_])_([^_]+)_$/ 이 정규식을 확인하는 코드는 삭제했다.

아래와 같은 식으로...

createInputRules() {
    return [markInputRule({
      regexp: /(?:^|[^*])\*([^*]+)\*$/,
      type: this.type,
      ignoreWhitespace: true,
      updateCaptured: _ref => {
        var fullMatch = _ref.fullMatch,
            start = _ref.start;
        return !fullMatch.startsWith('*') ? {
          fullMatch: fullMatch.slice(1),
          start: start + 1
        } : {};
      }
    })];
  }

 

이렇게 customExtension을 만들어서 기본적인 ItalicExtension class대신 바꿔서 껴 주니 잘 동작이 된다.

 

 

 

 

이 문제 때문에 얼마나 코드를 까보고 삽질을 했는지ㅠ.ㅠ

그래도 해결!

728x90
반응형