Goto Markdown Section

This action let’s you quickly jump to a Markdown heading.

Action Directory link: http://actions.getdrafts.com/a/1GF

fix non unique section headers

1 Like

Good idea and nicely done.

A variant FWIW, using Array.reduce (and line numbers for unique header keys)

(() => {

   const
       rgx = /^#+/,
       dct = draft.content.split('\n')
       .reduce(
       		// Accumulator updates.
           (a, x, i) => {
               const 
               	bln = rgx.test(x),
               	k = bln ? ( // Header with line number
               		x + ' (' + (1 + i) + ')'
               	) : '';
               return {
                   hp: bln ? (
                   		Object.assign(
                   			a.hp, 
                   			{
                   				[k]: a.pos + x.length
                   			}
                   		)
                   	) : a.hp,
                   p: ((bln ? a.p.addButton(k) : null), a.p),
                   pos: a.pos + x.length + 1
               };
           }, 
           // Initial state of accumulator.
           {
               hp: {},
               pos: 0,
               p: Object.assign(
                   Prompt.create(), {
                       title: 'Section:',
                       isCancellable: true
                   }
               )
           }
       );
	return (
		Object.keys(dct.hp).length > 0 ? (
			dct.p.show() ? (
				editor.activate(),
				editor.setSelectedRange(
					dct.hp[dct.p.buttonPressed],
					0
				),
				true 
			) : false
		) : false
	);
	
})();

Thanks. I tried lines numbers, but didn’t like the look (although it’s personal preference). Interesting to see a different approach.

Yes, I think I agree that line numbers everywhere gets a bit noisy.

I guess one approach might be to add them only where the plain header collides with a duplicate.

k = bln ? ( // Header (w. line number if duplicate)
    x + (Boolean(a.hp[x]) ? ' – line ' + (1 + i) : '')
) : '';

Updated version – click to expand
(() => {
    // Ver 0.2 (Line numbers only where headers are duplicate)
    const
        rgx = /^#+/,
        dct = draft.content.split('\n')
        .reduce(
            // Accumulator updates.
            (a, x, i) => {
                const
                    bln = rgx.test(x),
                    k = bln ? ( // Header (w. line number if duplicate)
                        x + (Boolean(a.hp[x]) ? ' – line ' + (1 + i) : '')
                    ) : '';
                return {
                    hp: bln ? (
                        Object.assign(
                            a.hp, {
                                [k]: a.pos + x.length
                            }
                        )
                    ) : a.hp,
                    p: ((bln ? a.p.addButton(k) : null), a.p),
                    pos: a.pos + x.length + 1
                };
            },
            // Initial state of accumulator.
            {
                hp: {},
                pos: 0,
                p: Object.assign(
                    Prompt.create(), {
                        title: 'Section:',
                        isCancellable: true
                    }
                )
            }
        );
    return (
        Object.keys(dct.hp).length > 0 ? (
            dct.p.show() ? (
                editor.activate(),
                editor.setSelectedRange(
                    dct.hp[dct.p.buttonPressed],
                    0
                ),
                true
            ) : false
        ) : false
    );
})();

For what it’s worth, this was the Navigate Draft action I had in my review. I’ve gone in and made it listed.

Is there a particular reason for which you are concluding a number of of your script steps with context.cancel() ?

(It’s not needed to bring a script step to its conclusion, but it would interrupt any multi-step action in which that script step was included, and prevent it from finishing).

As I understand it, context.cancel(), is really just for when you need one of the steps to make a premature interruption of the whole action, possibly accompanied by an explanation.

The explanation: copied from another action that included it. I like having it there, just in case I cancel something. As I’ve copied over multiple scripts from action to action, it’s just easier to keep it there. Doesn’t hurt it.

On the other hand, in the context of others similarly copy-pasting from you,

(and very understandably getting the impression that it’s just part of handling a menu cancellation),

further action steps could be placed after it, where it could spring a nasty surprise – interrupting not just a menu, but actually preventing all further steps from being executed.

It’s a bit of a bomb, with a deceptively innocent-sounding name, and one which leaves no explanation of what has happened – no message or notification. Perhaps better suited to your private copies than to shared copies ?

Or perhaps worth a comment, for the protection of other people’s time and data, or even just to prevent confusion ?

I’ve already stated in multiple places that I’m not the best programmer; if people are looking to me for expert-level programming, they need to keep on looking. Anyone using my scripts should know that it’s what has worked for me, but it might not work for others, especially if they are going to modify it or put it into another action. If someone chooses to take what I’ve done an modify it, they are on their own.

I share the actions that I do to help and/or inspire others to do their own thing. It shows what is possible, but might not be the right idea for everyone. I’m not going to get in the habit of having two actions – one for personal and one for private – because I do not want to maintain it. I’ll only do that when it comes to personal data being shared.

4 Likes