Skip to content

Commit f8282c6

Browse files
committed
feat(commands): magic formatting: magic quotes
1 parent cfbd402 commit f8282c6

File tree

3 files changed

+73
-49
lines changed

3 files changed

+73
-49
lines changed

src/app.ts

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@ import {
1919

2020
splitByLines, splitBySentences, splitByWords,
2121
removeNewLines, removeHTML, parseYoutubeTimestamp,
22-
lowerCase, upperCase, titleCaseWords, titleCaseSentences, magicBold,
22+
lowerCase, upperCase, titleCaseWords, titleCaseSentences,
2323
} from './commands'
24+
import { MARKUP, magicQuotes, magicWrap } from './commands/magic_markup'
2425
import { improveCursorMovementFeature, improveSearchFeature, spareBlocksFeature } from './features'
2526
import { borderView, columnsView, galleryView, hideDotRefs, tabularView } from './views'
2627
import { getChosenBlocks, p, scrollToBlock } from './utils'
27-
import { magicCode, magicHighlight, magicItalics, magicRef, magicStrikethrough, magicTag, magicUnderline } from './commands/magic_markup'
2828

2929

3030
const DEV = process.env.NODE_ENV === 'development'
3131

3232
const defaultSpareBlocksSpace = 20
33+
const defaultMagicQuotes = '""'
3334

3435
const settingsSchema: SettingSchemaDesc[] = [
3536
{
@@ -50,6 +51,15 @@ const settingsSchema: SettingSchemaDesc[] = [
5051
`.trim(),
5152
default: null,
5253
},
54+
{
55+
key: 'magicQuotes',
56+
title: 'Use this quotes for «Magic quotes» command',
57+
description: `
58+
<p>Default is <code>${defaultMagicQuotes}</code>.</p>
59+
`.trim(),
60+
type: 'string',
61+
default: defaultMagicQuotes,
62+
},
5363
{
5464
key: 'headingFeatures',
5565
type: 'heading',
@@ -208,6 +218,18 @@ async function postInit(settings) {
208218
await onAppSettingsChanged(settings, undefined)
209219
}
210220
async function onAppSettingsChanged(current, old) {
221+
if (current.magicQuotes !== old?.magicQuotes) {
222+
if (current.magicQuotes.length === 0)
223+
current.magicQuotes = defaultMagicQuotes
224+
if (current.magicQuotes.length === 1)
225+
current.magicQuotes += current.magicQuotes
226+
if (current.magicQuotes.length > 2)
227+
current.magicQuotes = current.magicQuotes.slice(0, 2)
228+
229+
if (current.magicQuotes !== logseq.settings!.magicQuotes)
230+
logseq.settings!.magicQuotes = current.magicQuotes
231+
}
232+
211233
if (!old || current.enableHomeEnd !== old.enableHomeEnd) {
212234
improveCursorMovementFeature(false)
213235
if (current.enableHomeEnd === 'Yes')
@@ -447,42 +469,65 @@ async function main() {
447469
label: ICON + ' Magic **bold**', key: 'mc-7-update-14-magic-bold',
448470
// @ts-expect-error
449471
keybinding: {},
450-
}, (e) => updateBlocksCommand(magicBold, false, false))
472+
}, (e) => updateBlocksCommand(
473+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.bold)},
474+
false, false))
451475
logseq.App.registerCommandPalette({
452476
label: ICON + ' Magic _italics_', key: 'mc-7-update-15-magic-italics',
453477
// @ts-expect-error
454478
keybinding: {},
455-
}, (e) => updateBlocksCommand(magicItalics, false, false))
479+
}, (e) => updateBlocksCommand(
480+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.italics)},
481+
false, false))
456482
logseq.App.registerCommandPalette({
457483
label: ICON + ' Magic ~~strikethrough~~', key: 'mc-7-update-16-magic-strikethrough',
458484
// @ts-expect-error
459485
keybinding: {},
460-
}, (e) => updateBlocksCommand(magicStrikethrough, false, false))
486+
}, (e) => updateBlocksCommand(
487+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.strikethrough)},
488+
false, false))
461489
logseq.App.registerCommandPalette({
462490
label: ICON + ' Magic ==highlight==', key: 'mc-7-update-17-magic-highlight',
463491
// @ts-expect-error
464492
keybinding: {},
465-
}, (e) => updateBlocksCommand(magicHighlight, false, false))
493+
}, (e) => updateBlocksCommand(
494+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.highlight)},
495+
false, false))
466496
logseq.App.registerCommandPalette({
467497
label: ICON + ' Magic underline', key: 'mc-7-update-18-magic-underline',
468498
// @ts-expect-error
469499
keybinding: {},
470-
}, (e) => updateBlocksCommand(magicUnderline, false, false))
500+
}, (e) => updateBlocksCommand(
501+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.underline)},
502+
false, false))
471503
logseq.App.registerCommandPalette({
472504
label: ICON + ' Magic `code`', key: 'mc-7-update-19-magic-code',
473505
// @ts-expect-error
474506
keybinding: {},
475-
}, (e) => updateBlocksCommand(magicCode, false, false))
507+
}, (e) => updateBlocksCommand(
508+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.code)},
509+
false, false))
476510
logseq.App.registerCommandPalette({
477511
label: ICON + ' Magic [[reference]]', key: 'mc-7-update-20-magic-ref',
478512
// @ts-expect-error
479513
keybinding: {},
480-
}, (e) => updateBlocksCommand(magicRef, false, false))
514+
}, (e) => updateBlocksCommand(
515+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.ref)},
516+
false, false))
481517
logseq.App.registerCommandPalette({
482518
label: ICON + ' Magic #tag', key: 'mc-7-update-21-magic-tag',
483519
// @ts-expect-error
484520
keybinding: {},
485-
}, (e) => updateBlocksCommand(magicTag, false, false))
521+
}, (e) => updateBlocksCommand(
522+
(content, level, block, parent) => {return magicWrap(block, content, MARKUP.tag)},
523+
false, false))
524+
logseq.App.registerCommandPalette({
525+
label: ICON + ' Magic "quotes"', key: 'mc-7-update-22-magic-quotes',
526+
// @ts-expect-error
527+
keybinding: {},
528+
}, (e) => updateBlocksCommand(
529+
(content, level, block, parent) => {return magicQuotes(block, content, settings.magicQuotes)},
530+
false, false))
486531

487532

488533
// Navigation

src/commands/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import {
1212
transformSelectedBlocksWithMovements, unique, walkBlockTree, walkBlockTreeAsync,
1313
} from '../utils'
1414

15-
import { magicBold } from './magic_markup'
16-
1715

1816
// there is no `saw` emoji in Windows — use `kitchen knife`: it has the same colors
1917
export const ICON = isWindows ? '🔪' : '🪚'
@@ -999,5 +997,3 @@ export function parseYoutubeTimestamp(content, level, block, parent) {
999997
replacer,
1000998
)
1001999
}
1002-
export { magicBold }
1003-

src/commands/magic_markup.ts

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class MarkUp implements Iterable<[string, string]> {
6464
}
6565
}
6666

67-
const MARKUP: {[type: string]: MarkUp } = {
67+
export const MARKUP: {[type: string]: MarkUp } = {
6868
bold: new MarkUp({
6969
wrap: ['**', '**'],
7070
unwrap: [['<b>', '</b>']] }),
@@ -92,7 +92,6 @@ const MARKUP: {[type: string]: MarkUp } = {
9292
alternativeWrapWhenMatch: /\s+/,
9393
alternativeWrapIndex: 1, }),
9494
}
95-
type MARKUP_NAME = keyof typeof MARKUP
9695

9796
const TRIM_BEGIN = [
9897
/^\s+/, // spaces at the beginning
@@ -302,12 +301,10 @@ function expand(line: string, markup: MarkUp, selectPosition: [number, number])
302301
})
303302
}
304303

305-
function applyMarkup(line: string, markupName: MARKUP_NAME, selectPosition?: [number, number]): string {
304+
function applyMarkup(line: string, markup: MarkUp, selectPosition?: [number, number]): string {
306305
if (!line && !selectPosition)
307306
return ''
308307

309-
const markup = MARKUP[markupName]
310-
311308
const isSelectionMode = Boolean(selectPosition)
312309
if (!selectPosition)
313310
selectPosition = [0, line.length]
@@ -340,9 +337,9 @@ function applyMarkup(line: string, markupName: MARKUP_NAME, selectPosition?: [nu
340337
}
341338
}
342339

343-
function wrap(block: BlockEntity, content: string, markupName: MARKUP_NAME) {
340+
export function magicWrap(block: BlockEntity, content: string, markup: MarkUp) {
344341
if (!block._selectPosition)
345-
return content.split('\n').map((line) => applyMarkup(line, markupName)).join('\n')
342+
return content.split('\n').map((line) => applyMarkup(line, markup)).join('\n')
346343

347344
let lineStartPosition = 0
348345
let newLineStartPosition = 0
@@ -380,7 +377,7 @@ function wrap(block: BlockEntity, content: string, markupName: MARKUP_NAME) {
380377
Math.max(selectStart - lineStartPosition, 0),
381378
Math.min(selectEnd - lineStartPosition, line.length),
382379
]
383-
const newLine = applyMarkup(line, markupName, wholeLine ? undefined : selectPositionLine)
380+
const newLine = applyMarkup(line, markup, wholeLine ? undefined : selectPositionLine)
384381

385382
if (!wholeLine) {
386383
// first line of selection
@@ -401,34 +398,20 @@ function wrap(block: BlockEntity, content: string, markupName: MARKUP_NAME) {
401398
return wrapped
402399
}
403400

404-
export function magicBold(content, level, block, parent) {
405-
return wrap(block, content, 'bold me')
406-
}
407-
408-
export function magicItalics(content, level, block, parent) {
409-
return wrap(block, content, 'italics')
410-
}
411-
412-
export function magicStrikethrough(content, level, block, parent) {
413-
return wrap(block, content, 'strikethrough')
414-
}
415-
416-
export function magicHighlight(content, level, block, parent) {
417-
return wrap(block, content, 'highlight')
418-
}
401+
export function magicQuotes(block: BlockEntity, content: string, quotes: string) {
402+
const wrap: [string, string] = [quotes[0], quotes[1]]
403+
const unwrap: ([string, string] | null)[] = [
404+
['«', '»'], ['"', '"'], ["'", "'"], ['“', '“'], ['‘', '‘']]
419405

420-
export function magicUnderline(content, level, block, parent) {
421-
return wrap(block, content, 'underline')
422-
}
423-
424-
export function magicCode(content, level, block, parent) {
425-
return wrap(block, content, 'code')
426-
}
406+
for (const [i, pair] of Object.entries(unwrap)) {
407+
if (pair && pair[0] == wrap[0] && pair[1] == wrap[1]) {
408+
unwrap.splice(Number(i), 1)
409+
break
410+
}
411+
}
427412

428-
export function magicRef(content, level, block, parent) {
429-
return wrap(block, content, 'ref')
430-
}
413+
console.log('TRACING', {wrap, unwrap})
431414

432-
export function magicTag(content, level, block, parent) {
433-
return wrap(block, content, 'tag')
415+
const quotesMarkup = new MarkUp({wrap, unwrap})
416+
return magicWrap(block, content, quotesMarkup)
434417
}

0 commit comments

Comments
 (0)