npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@salespreso/slide-tools

v1.2.2

Published

some scripts to help manage the creation of new slides and sections

Downloads

11

Readme

SLIDE TOOLS

Installation

When using slide-tools as a part of your content development workflow.

  • check out your chosen LivePreso deck
  • run yarn add -D @salespreso/slide-tools

Development

When upgrading and adding new features to the slide-tools project.

  • check out the project to a location of your choice
  • run yarn
  • run yarn link
  • open the LivePreso deck directory you wish to test against
  • run yarn link "@salespreso/slide-tools"

Contents



add_slide and add_section

These commands use inquirer.js to build a series of questions to be answered by the user in order to create a section or slide.

Some questions, such as slide or section ID, where within a section a slide should be inserted, are always asked. The user inputs are assembled in an object. For a new slide they look like this:

{ sectionId: 'property_journey_rent',
  insertIndex: 2,
  slideId: 'dave',
  slideTitle: 'Dave',
  template: 'columns'
}

Because inquirer.js takes a plain JS object as the configuration for its series of prompts / questions, a given template can request template-specific questions by defining a JSON file (parameters.json) in its template root. This can then generate an extended, template-specific series of values for the the template to utilise.

For instance, the columns template needs to know the column setup for the slide (how many columns, the width of each etc). When the addslide command is added, and a columns template selected, a second data object is created.

{ classes: ['collapsed', 'animated'],
  height: 'column-group--height-half',
  columns:
   [
     { width: '1', uid: 'frank', bg_colour: '' },
     { width: '2', uid: 'charlie', bg_colour: 'l-grey-50' }
   ]
}

templates

Templates are done using lodash / underscores tags. When the template is supplied with specific vars, the slideId & slideTitle from the global options are included, to do fundamentals like the scss selector for the slide.

In order to cleanly guard against undefined variables in the template's variable scope (which can cause exceptions), all vars are scoped under a 'data' variable. So a simple template tag looks like this:

<%= data.slideTitle %>

In the columns template case, the template contains a loop to generate columns. It also has a need to know the total number of columns, in order to define which class to apply to the grid as a whole, for column widths. Instead of asking up front, for this value, it can be calculated within the template, using plain JS:

<% columnTotal=0;
   for (var i = 0; i < data.columns.length; ++i) {
    columnTotal+=parseInt(data.columns[i].width);
   }
%>

configuration and prompt types

Inquirer.js ships with a number of predefined prompt types. I've added 3 third-party extensions to those on offer. One of these (inquirer-select-line) is used in the core configuration, to determine where a slide is inserted in the section's slide sequence. The others are loaded only so that they can be utilised by individual templates. If there is a specific need for additional 3rd party prompts, we can add a require() statement for it in the script, to make it available.

usage

these instructions may change depending on how the tools are ultimately packaged The tools shoud be run from the project root. If the project.yaml is not found in the cwd, the script will exit.

node ./slide_tools/slide_tools.js [command]

Where command is one of addsection or add_slide.

The addsection command exposes the entered section ID and section title as slideId and slideTitle to the template. This allows slide & section templates to be used interchangeably (unsure if there is value in this). percent

under the hood

Various checks are currently performed.

  • if the section ID to be created already exists, the script will exit
  • if a given slide ID already exists (or a folder with that ID exists), the script will exit
  • there is currently no check for global uniqueness for slide IDs (as required by imposter); this could easily be added.

Once the checks pass

  • the template directory is copied to its destination
  • the parameters.json removed, if it exists
  • the files found (index.html or index.njk, slide.scss) there are loaded, the templates run, and the result is written back to the same file.

add_editable_ids

This command uses shortid.js to add unique keys to HTML elements tagged with the data-companywide-editable and data-companywide-editable-image tags. The script looks for article tags in each index.html to determine the slide's id, and creates keys with the form:

data-companywide-...="[slide_id]_editable_[shortid]"

The keys will only be added to the companywide attribute if there isn't one already, so you can run this multiple times on the same project and it won't clobber your old keys.


export_deck command

Run from the project root, it can be used to create a child deck from the current one, in a unique dir, ready for upload.

Takes the following switches

  • -d <targetdir> destination dir for the place you are exporting tool
  • -y <child.yaml> a unqiue yaml file for this deck

The child.yaml only needs 2 keys - key and sections. The child.yaml is merged with the project.yaml using _.default(), so the potential exists to have other child-unique keys, such as hooks.

When run, the script reads the project.yaml and child.yaml, creates the target directory, copies the dist directory and creates a new merged project.yaml inside it (as well as an empty src directory).

The resulting output directory can then be loaded into the CDK and uploaded, under its own unique key.

Examples:

slide_tools export_deck -d ../product-showcase -y product-showcase.yaml

This example creates/replaces a directory one level back call "product-showcase" based on the child project yaml requirements specified in "product-showcase.yaml".

Migrating slides

If a slide exists in the child.yaml but is not found in the corresponding section of the source yaml, then it will searched for by key, and migrated from elsewhere in the source deck, if found. If it is not found, the script will exit.

If a section exists in the target deck, but not the source, an error will be thrown (as the resulting section will be missing a title slide).

templates

A child yaml's sections and slides can specify if they wish to use a slide from the parent.yaml as a template. This is done by adding meta_template to the desired section/slide with a path of section_key/slide_key to declare which section/slide you wish to use as the template. Templated slides in the child.yaml will then be built out by copying over the specified templates.

slides

If no slides are declared for a section using a template, the template section's slides will be copied over to along with the rest of the section's files. If slides are specified for a section using a template, these will be used instead of the template section's slides. In order to omit slides from a section using a template, you will need to declare an empty array.

tags

Similar to a section's slides, if no tags are specified for a child.yaml section/slide using a template, they will receive the template's tags. If tags are declared, none of the template section/slide's tags will be copied over. If you do not wish for any tags to be applied to the resulting section/slide, you must declare an empty array.

variables

Any occurances of the template section/slide's key or title in the index.html, slide.css, slide.js or svgs of the desintation slide will be replaced by the key and title of the section/slide as declared in the child.yaml.

If the template section's slides are in use, the section's key and title will also flow through to the generated slides. Both the section key/title and slide key/title can be declared in a template section's slides, and will be replaced accordingly in these use-cases.

Additional vars can be specified using meta_template.vars.

Example

parent.yaml

...
sections:
   -
      key: introduction
      title: Introduction
      slides:
         - { key: standard_slide, title: Standard slide }
   -
      key: template_divider_section
      title: Section (template)
      slides:
         - { key: template_performance_slide, title: Performance Slide (template) }
         - { key: template_stats_slide, title: Stats Slide (template) }

child.yaml

...
sections:
   -
      key: introduction
      title: Introduction
      slides:
         - { key: standard_slide, title: Standard slide }
   -
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
      # No slides have been specified, slides will be generated
      # using slides included in the template section
   -
      key: kew_office
      title: Kew Office
      meta_template:
         path: template_divider_section
      slides:
         -
            key: kew_performance
            title: Kew Performance
            meta_template:
               path: template_performance_slide
         # Slides have been specified, this will be used instead of the
         # section template's slides
   -
      key: prahran_office
      title: Prahran Office
      meta_template:
         path: template_divider_section
      slides: []
         # No slides will be included in this section
   -
      key: malvern_office
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
         vars:
            occupants: 10
            cost: 150
            # Any occurances of these var keys in the template_divider_section
            # will be replaced with these values when the child deck is built out

Example:

child.yaml

...
sections:
   -
      key: malvern_office
      key: malvern_office
      title: Malvern Office
      meta_template:
         path: template_divider_section
         vars:
            occupants: 10
            cost: 150
            # Any occurances of these var keys in the template_divider_section
            # will be replaced with these values when the child deck is built out

import_state command

allow you to inject a full set of feeds and a context into the CDK application, based on either a onlinepreso invite link, or a file generated within the App itself.

usage

from a url

slide_tools import_state --title="New Test Feed Name" --url=<your preso url> - import from a preso URL. IN this case the URL is parsed and /bundle is added to put the configuration of the presentation.

from a file

slide_tools import_state --title="New Test Feed Name" --file=<file path> - import from a file exported from the app. The format of a file for import is a simple json object with context and feeds top level keys. A sample export script, that can be pasted into the console of the App, is as follows;

var extractDataTo = function(fileName) {
    var comboBlob = { feeds: Bridge.Feed.feeds, context: Bridge.Context.getDict()};
    var fs = nw.require("fs");
    var path = nw.require("path");
    var os = nw.require("os");
    var outputFile = path.resolve(os.homedir(), fileName);
    fs.writeFileSync(outputFile, JSON.stringify(comboBlob, null, 2));
};

Calling the above with extractDataTo("output.json"); will create output.json in the root of the user's home directory.

import_state will not overwrite the existing feeds.json and context.json files in your project's data directory, unless you explicitly use the --execute switch. Without it, the script will generate a pair of new JSON files taht you can compare to the originals, and then replace if you are happy. This behaviour is a safeguard while any bugs are worked out. When --execute is specified, a feeds.json.bak will be saved to allow rollback to the previous state.


earlier notes

On next running gulp, you may see a nunjucks error, but it's not in the generated output, I think nunjucks is trying to compile the raw templates (with underscores tags in them). The selector for *.njk files needs to be tightened to only include those in src

Copying the slide_tools and templates folder across to a fresh project, and then creating / editing templates to suit, will allow the code to be recycled; ultimately, it should be wound in to the gulp tasks, as there's nothing here that's project specific. Would just need a few more checks / warnings to make sure the template directories existed.