Froala·TinyMCE·CKEditor 5·Quill — 어떤 범용 WYSIWYG 에디터도 Word처럼 여백과 들여쓰기를 끌어서 조절하는 줄자를 제공하지 않습니다. editor-ruler는 에디터에 종속되지 않는 코어와 얇은 어댑터로 그 공백을 채우는 오픈소스입니다.
문단을 클릭하면 그 문단의 여백, 테이블 셀을 클릭하면 컬럼 마커 + 테이블 통째 이동, 이미지를 선택하면 소속 블록이 밀립니다. 줄자 빈 곳에서 아래로 끌면 가로 가이드, 툴바 드롭다운으로 세로 줄자·단위 전환. "Unlicensed" 표시는 Froala 트라이얼 워터마크로 이 플러그인과 무관합니다.
Tiptap 에디터 로딩 중…
Tiptap은 헤드리스 에디터라 툴바가 원래 없습니다 — 위 미니 툴바는 데모용으로 직접 배선한 것이고, 코어 탭과의 차이는 문서 모델(노드 속성 저장·undo 통합·getHTML 직렬화)입니다. 모듈은 CDN(esm.sh)에서 불러오며 네트워크에 따라 잠시 걸릴 수 있습니다.
CKEditor 5 로딩 중…
CKEditor 5 모듈을 CDN에서 불러옵니다 — 네트워크에 따라 잠시 걸릴 수 있습니다. 이미지는 CKEditor 이미지 플러그인 구성에 따라 동일하게 동작합니다.
프레임워크 없이 createRuler + createGuides만으로 만든 순수 contenteditable 데모 — 어댑터들이 쓰는 코어 그대로입니다.
npm install @devslab/editor-ruler
import { createRuler } from '@devslab/editor-ruler';
const ruler = createRuler(mountElement, {
unit: 'cm', // 'cm' | 'in' | 'px'
getMetrics: () => ({ contentWidth, leftMargin, rightMargin, firstLineIndent }), // px
onChange(change, phase) {
// px 값을 현재 문단(들)에 적용; 드래그를 놓는 순간 phase === 'commit'
},
});
ruler.refresh(); // 선택/내용이 바뀔 때 호출
ruler.setUnit('in'); // 눈금 전환
번들러 없이 <script> 한 줄로 씁니다. 전역 EditorRuler가 노출됩니다.
<script src="https://cdn.jsdelivr.net/npm/@devslab/editor-ruler@0.12.0/dist/index.global.js"></script>
<script>
const ruler = EditorRuler.createRuler(document.getElementById('ruler-mount'), {
unit: 'cm',
getMetrics: () => ({ /* ... */ }),
onChange(change) { /* ... */ },
});
</script>
Froala 어댑터도 동일합니다: @devslab/editor-ruler-froala/dist/index.global.js를 로드하면 전역 EditorRulerFroala.defineRulerPlugin이 노출됩니다 (코어 포함 단일 파일).
버전 지정: @0.10.0(정확 고정) · @0.10(패치 자동 반영 — 권장) · @latest(항상 최신 — 메이저 포함이라 브레이킹 체인지 위험, jsDelivr가 별칭을 최대 12시간 캐시).
npm install @devslab/editor-ruler-froala froala-editor
import FroalaEditor from 'froala-editor';
import { defineRulerPlugin } from '@devslab/editor-ruler-froala';
defineRulerPlugin(FroalaEditor); // 인스턴스 생성 전에 1회
new FroalaEditor('#editor', {
rulerEnabled: true, // 기본 true
rulerUnit: 'cm',
// 줄자 옵션 통합 드롭다운 (보이기/숨기기 + 세로 줄자 + 가이드 + 단위):
toolbarButtons: ['bold', 'italic', '|', 'rulerOptions'],
// 따로 쓰고 싶으면 'toggleRuler', 'rulerUnit'도 각각 등록돼 있습니다
});
defineRulerPlugin은 표준 Froala 플러그인(ruler)과 함께 줄자 아이콘 드롭다운
rulerOptions를 등록합니다 — 보이기/숨기기·세로 줄자·가이드 잠금/지우기·cm/inch/px가 한 버튼에 있고
활성 상태가 체크로 표시됩니다. pluginsEnabled를 직접 지정한다면 'ruler'를 포함하세요.
드래그는 선택 문단의 margin-left/right·text-indent를 갱신하고 제스처당 undo 스텝을 1회 기록합니다.
npm install @devslab/editor-ruler-tiptap @tiptap/core
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import { EditorRuler } from '@devslab/editor-ruler-tiptap';
new Editor({
element,
extensions: [StarterKit, EditorRuler.configure({ unit: 'cm' })],
content: '<p>Hello</p>',
});
들여쓰기는 rulerIndent 노드 속성으로 저장되어 getHTML()에 순수 인라인 CSS로 나오고, 드래그 전체가 undo 한 단계입니다. Tiptap v2·v3 지원.
| createRuler(mount, options) | 줄자를 마운트하고 Ruler 핸들을 반환 — guides·columns·guideSnap 옵션 포함 |
|---|---|
| options.getMetrics() | { contentWidth, leftMargin, rightMargin, firstLineIndent } — 전부 px |
| options.onChange(change, phase) | 드래그 중 'drag', 놓는 순간 'commit' (undo 경계) |
| createGuides(container, options) | 가이드선 컨트롤러 — list/set/clear/setLocked/setVisible |
| createVRuler(mount, options) | 세로 눈금 스트립 (가이드 생성 지원) |
| ruler.refresh() / setUnit(u) / destroy() | 메트릭 갱신 · 눈금 전환 · 정리 |
핸들과 컬럼 마커는 ARIA 슬라이더입니다 — ←/→ 1px, Shift 10px, Home/End. 테마는 --edr-* CSS 변수, UI 언어는 브라우저를 따릅니다(ko/en 내장).
결과물 HTML은 어떻게 나오나요? 순수 인라인 CSS입니다 — <p style="margin-left: 75px; text-indent: 38px">. 어디로 내보내도(메일·다른 페이지·CMS) 레이아웃이 유지됩니다.
테이블·이미지는요? Word처럼 다 밀립니다 — 테이블 안에 커서를 두고 드래그하면 테이블 전체가 이동하고, 셀 안 문단은 개별 들여쓰기, 이미지는 소속 블록과 함께 움직입니다. 테이블 안에서는 줄자에 컬럼 경계 마커가 떠서 드래그로 컬럼 폭도 조절됩니다 (병합 셀 테이블 제외).
가이드선은 문서에 남나요? 아니요 — 순수 시각 오버레이라 내보내는 HTML에 전혀 남지 않습니다. 정렬 참고용이며, 드롭다운에서 잠그거나 한 번에 지울 수 있고, 드래그 중 핸들과 컬럼 마커가 가이드 근처에서 스냅됩니다.
탭 스톱은요? HTML에는 탭 스톱 모델이 없어 의도적으로 범위 밖입니다. 여백·들여쓰기는 CSS와 1:1이라 어디서나 안전하게 동작합니다.
다른 에디터는요? 코어가 에디터 불문이라 어댑터는 "선택 블록 읽기/스타일 쓰기/undo 연결"만 하면 됩니다 — Froala·Tiptap 어댑터가 예시이고 CKEditor 5가 다음입니다.