Code Monkey home page Code Monkey logo

sassdown's Introduction

sassdown

Grunt plugin for building living styleguides with Handlebars from Markdown comments in CSS, Sass and LESS files.

Note: This plugin is in semi-active development! So expect it to be a little rough around the edges. If you have any questions, issues or suggestions get in touch. Currently on version 0.2.7.

  1. Getting started
  2. Sassdown task
  3. Markdown
  4. Handlebars
  5. Highlight.js
  6. Data Objects
  7. Template
  8. Sass

What's new in version 0.2.7?

  • Path resolving is relative; no more issues serving from localhost or using file:// protocols
  • Whitespace and preformatting is preserved in markup results
  • Source styles shown in conjunction with markup and result
  • Pages are served form an array-literal node tree; meaning clearer and nested navigation
  • Comment block matching is modifiable via regular expressions
  • Choice of syntax highlighting styles from various popular Highlight.js themes
  • Syntax highlighting is done with Node before templates compile; faster page loads

Getting started

Install this plugin with this command:

npm install sassdown --save-dev

Enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('sassdown');

Sassdown Task

Run the task using grunt sassdown. Task targets, files and options may be specified according to the grunt configuring tasks guide.

Overview

In your project's Gruntfile, add a section named sassdown to the data object passed into grunt.initConfig().

sassdown: {
    options: {
        // Task-specific options go here.
    },
    target: {
        // Target-specific file lists and/or options go here.
    },
},

Options

options.assets

Type: Array
Default: null

Optional. Array of file paths. Will be included into the styleguide output. Supports globbing. Supports relative and absolute file paths (eg. http://, https://, // or even file://).

options.template

Type: String
Default: null

Optional. A path to a Handlebars template file. Will use default Sassdown template if left blank.

options.handlebarsHelpers

Type: Array
Default: null

Optional. Array of file paths. The Handlebars helpers will be available to use in the template. Supports globbing. Supports relative and absolute file paths (eg. http://, https:// or even file://).

options.theme

Type: String
Default: null

Optional. A path to a theme stylesheet. Will use default Sassdown theme if left blank.

options.readme

Type: String
Default: null

Optional. Path to a README file. When set, this file will be parsed with Markdown and used as the index page for the styleguide.

options.highlight

Type: String
Default: github

Optional. Choice of syntax highlighting style. Defaults to github, but other available options are: docco, monokai, solarized-light, solarized-dark or xcode.

options.scripts

Type: Array
Default: null

Optional. Array of file paths. The scripts will be linked with script tags with src attributes. Supports globbing. Supports relative and absolute file paths (eg. http://, https://, // or even file://).

If this option is set the default scripts won't be included, but you can include them again by adding node_modules/sassdown/tasks/data/scripts.js to the file list, or by copying and modifying that file.

options.commentStart

Type: RegExp
Default: /\/\*/

Optional. A regular expression to match beginning part of a comment block. Defaults to regular block comment (/*).

options.commentEnd

Type: RegExp
Default: /\*\//

Optional. A regular expression to match ending part of a comment block. Defaults to regular block comment (*/).

options.excludeMissing

Type: Boolean
Default: false

Optional. When set to true, Sassdown will ignore any files that do not contain matching or valid comment blocks.

options.dryRun

Type: Boolean
Default: false

Optional. When set to true, Sassdown will not generate any files, and will exit with status 1 if any files do not contain matching or valid comment blocks.

Usage

You will need to use an expanded files object, but here is roughly the minimum configuration required.

sassdown: {
    styleguide: {
        options: {
            assets: ['public/css/*.css']
        },
        files: [{
            expand: true,
            cwd: 'src/sass',
            src: ['*.scss'],
            dest: 'public/styleguide/'
        }]
    }
},

On larger projects you may need to include additional assets and customise the output with a user theme, template and scripts.

sassdown: {
    styleguide: {
        options: {
            assets: [
                'public/css/**/*.min.css',
                'public/js/*.min.js',
                'http://use.typekit.net/sea5yvm.js',
            ],
            theme: 'src/styleguide/theme.css',
            template: 'src/styleguide/template.hbs',
            scripts: ['src/styleguide/*.js'],
            readme: 'src/assets/sass/readme.md',
            highlight: 'monokai',
            excludeMissing: true
        },
        files: [{
            expand: true,
            cwd: 'src/assets/sass',
            src: [
                'partials/**/*.{scss,sass}',
                'modules/**/*.{scss,sass}'
            ],
            dest: 'public/styleguide/'
        }]
    }
},

Markdown

Sassdown uses Markdown to parse any block comments in your Sass files. From these, it generates the text content in the styleguide. Any recognised code blocks will be rendered as HTML/SCSS source-result pairs.

Structure

You may use any Markdown-compatible heading syntax you like. You may use any common style of block-comment syntax you like. Code blocks may be fenced or indented (four spaces or one tab character). Below are several examples; each will be correctly parsed by Sassdown into identical output.

Example .scss file

/*

Alerts
======

Creates an alert box notification using the `.alert-` prefix. The following options are available:

    <div class="alert-success">Success</div> 
    <div class="alert-warning">Warning</div> 
    <div class="alert-error">Error</div>

*/
@mixin alert($colour){
    color: darken($colour, 50%);
    background: $colour;
    border-radius: 5px;
    margin-bottom: 1em;
    padding: 1em;
}
.alert-success { @include alert(#e2f3c1) }
.alert-warning { @include alert(#fceabe) }
.alert-error   { @include alert(#ffdcdc) }

Handlebars

Handlebars is a semantic templating syntax. Put simply, it allows you to output dynamic properties in HTML using {{var}} from a variety of data sources such as JSON.

Sassdown uses Handlebars to output data from the data objects it creates. Your .hbs file specified in the template option may contain code that looks like this for example:

{{#each page.sections}}
    <div class="section">
        {{#if comment}}
            <div class="comment">{{{comment}}}</div>
        {{/if}}
        {{#if result}}
            <div class="result">{{{result}}}</div>
        {{/if}}
        {{#if markup}}
            <div class="markup">{{{markup}}}</div>
        {{/if}}
        {{#if styles}}
            <div class="styles">{{{styles}}}</div>
        {{/if}}
    </div>
{{/each}}

Common partials

Sassdown also provides a series of Handlebars partials, which can be used to output specific information on each page. These are:

  • {{> root}}
    Outputs a path to the root directory of the styleguide, relative to whatever page you are on.

  • {{> assets}}
    Outputs a set of <link /> or <script> tags that include assets specified in the Grunt task options.

  • {{> theme}}
    Outputs the theme stylesheet, minified, into a <style> tag.

Handlebars helpers

You can add more features to Handlebar templates by using Helpers.

For example you could add a helper that capitalizes all text:

<big>{{uppercase shoutThis}}</big>

You load your helpers with the handlebarsHelpers option.

handlebarsHelpers: ['hb-helpers/**/*.js']

The helper module must export a function that does the registration, or else it won't load.

module.exports = function(Handlebars) {
    Handlebars.registerHelper('uppercase', function(input) {
      return typeof input === 'string' ? input.toUpperCase() : input;
    });
};

// This also works
module.exports = {
  register: function(Handlebars) {
    ...
}

Highlight.js

Sassdown uses the popular and well-supported Highlight.js for syntax highlighting. Markup is parsed by a Node module and highlighted before being output through the template. Various popular themes are supported via the task options.

Data Objects

Two objects are parsed into the Handlebars template; Page and Pages. Page contains json data for the current page only; Pages is an array literal containing all Page objects in a nested node tree.

Any property within these objects can be output by Handlebars using {{helpers}}. You can iterate through objects using {{#each}} ... {{/each}}, for example.

Page

{
  title: 'Alerts',
  slug: '_alerts',
  href: 'objects/user/_alerts.html',
  dest: 'test/example/styleguide/objects/user/_alerts.html',
  src: 'test/example/assets/sass/partials/objects/user/_alerts.scss',
  sections: [ 
    {
      id: 'mswbu',
      comment: '<h1 id="alerts">Alerts</h1>\n<p>Creates an alert box notification using the <code>.alert-</code> prefix. The following options are available:</p>\n',
      result: '\n<div class="alert-success">Success</div> \n<div class="alert-warning">Warning</div> \n<div class="alert-error">Error</div>\n',
      markup: '<pre><code><span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;</span>div</span> <span class="token attr-name" >class</span><span class="token attr-value" ><span class="token punctuation" >=</span>&quot;alert-success&quot;&gt;</span></span>Success<span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;/</span>div</span><span class="token punctuation" >&gt;</span></span> \n<span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;</span>div</span> <span class="token attr-name" >class</span><span class="token attr-value" ><span class="token punctuation" >=</span>&quot;alert-warning&quot;&gt;</span></span>Warning<span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;/</span>div</span><span class="token punctuation" >&gt;</span></span> \n<span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;</span>div</span> <span class="token attr-name" >class</span><span class="token attr-value" ><span class="token punctuation" >=</span>&quot;alert-error&quot;&gt;</span></span>Error<span class="token tag" ><span class="token tag" ><span class="token punctuation" >&lt;/</span>div</span><span class="token punctuation" >&gt;</span></span></code></pre>\n',
      styles: '<pre><code><span class="token keyword" >@mixin</span> alert(<span class="token variable" >$colour</span>)<span class="token punctuation" >{</span>\n    <span class="token property" >color</span><span class="token punctuation" >:</span> darken(<span class="token variable" >$colour</span>, 50%)<span class="token punctuation" >;</span>\n    <span class="token property" >background</span><span class="token punctuation" >:</span> <span class="token variable" >$colour</span><span class="token punctuation" >;</span>\n    <span class="token property" >border-radius</span><span class="token punctuation" >:</span> 5px<span class="token punctuation" >;</span>\n    <span class="token property" >margin-bottom</span><span class="token punctuation" >:</span> 1em<span class="token punctuation" >;</span>\n    <span class="token property" >padding</span><span class="token punctuation" >:</span> 1em<span class="token punctuation" >;</span>\n<span class="token punctuation" >}</span>\n\n.alert-success <span class="token punctuation" >{</span> <span class="token keyword" >@include</span> alert(#e2f3c1) <span class="token punctuation" >}</span>\n.alert-warning <span class="token punctuation" >{</span> <span class="token keyword" >@include</span> alert(#fceabe) <span class="token punctuation" >}</span>\n.alert-error   <span class="token punctuation" >{</span> <span class="token keyword" >@include</span> alert(#ffdcdc) <span class="token punctuation" >}</span></code></pre>\n'
    }
  ]
}

Pages

[
  {
    name: 'base',
    isDirectory: true,
    pages: [
      [Object],
      {
        name: 'typography',
        isDirectory: true,
        pages: [
          [Object],
          [Object],
          [Object]
        ]
      },
      [Object],
      [Object]
    ]
  },
  {
    name: 'partials',
    isDirectory: true,
    pages: [
      [Object],
      [Object]
    ]
  },
  {
    name: 'modules',
    isDirectory: true,
    pages: [
      [Object] 
    ]
  },
  {
    name: 'objects',
    isDirectory: true,
    pages: [
      [Object],
      [Object], 
      [Object]
    ]
  }
]

Template

Should you wish to create a new Sassdown template, you may wish to use the existing default template.hbs as a base to work from.

Sass

It should be noted that, despite the name, Sassdown does not explicitly read only Sass files. It works just fine with .sass, .less, .css or even .txt files.

Sassdown does not compile your source files. Assuming you are using SASS, and since you're using Grunt, I would recommend the grunt-contrib-compass plugin for this task. However you may also want to look at grunt-contrib-stylus.

Project Milestones

Current milestones for this project

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

sassdown's People

Contributors

carlosrberto avatar dwightjack avatar kennethsundqvist avatar m5o avatar mdix avatar paul66 avatar randallagordon avatar simons avatar winstromming avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sassdown's Issues

Reduce repetition and duplication in the File object

The existing File object contains several properties which are used only once, or sometimes not at all, and these could be removed for cleaner output. Some repeatedly conflict and duplicate properties in the Config object.

Example: prismLang can be removed during #22

We can remove site and groups by consolidating the Config object.

{
  slug: '_alerts',
  heading: 'Alerts',
  group: 'objects',
  path: 'public/styleguide/objects/_alerts.html',
  url: '/public/styleguide/objects/_alerts.html',
  original: 'assets/sass/partials/objects/_alerts.scss',
  prismLang: 'scss', // syntax highlight
  ext: 'scss' // file extension
  site: {
    root: 'styleguide/',
    rootUrl: '/public/styleguide/',
    groups: {
      modules: [Object],
      objects: [Object]
    },
    assets: '../../styleguide/assets/'
  },
  sections: [
    {
      id: 'cr3sor', // randomly generated
      prismLang: 'scss', // syntax highlight
      fileExt: 'scss' // file extension
      comment: '<h1>Alerts</h1>\n<p>Creates an alert box notification using the <code>.alert-</code> prefix. The following options are available:</p>',
      source: '<pre><code>&lt;div class=&quot;alert-success&quot;&gt;Success&lt;/div&gt;\n&lt;div class=&quot;alert-warning&quot;&gt;Warning&lt;/div&gt;\n&lt;div class=&quot;alert-error&quot;&gt;Error&lt;/div&gt;</code></pre>',
      cssSource: '<pre><code>@mixin alert($colour){\n    color: darken($colour, 50%);\n    background: $colour;\n    border-radius: 5px;\n    margin-bottom: 1em;\n    padding: 1em;\n}\n\n.alert-success { @include alert(#e2f3c1) }\n.alert-warning { @include alert(#fceabe) }\n.alert-error   { @include alert(#ffdcdc) }</code></pre>'
      result: '<div class="alert-success">Success</div> <div class="alert-warning">Warning</div> <div class="alert-error">Error</div>'
    }
  ]
}

Tag versions

The npm module is versioned, you even write the latest version number into the readme.
Imo you should also tag the repo with the version numbers.

Include array of Sass partials to ignore within the Grunt options

Provide an ignore_partials option within the Grunt task definition. This would be an array of Sass partials to be excluded when generating the styleguide pages.

This will provide a greater degree of control over what gets rendered to the styleguide. Partials containing Sass variables for example do not need to be included in the styleguide.

sassdown: {
    options: {
        template_assets: 'src/styleguide/assets',
        template_html: 'src/styleguide/template.hbs',
        css_output: 'assets/build/css/enhanced.min.css',
        ignore_partials: ['_settings-core.scss', '_settings-enhanced.scss']
    },

Sassdown.config.tree includes pages not in matched files

See #44

Sassdown will add to the node tree files and directories that were not defined as part of the Grunt task. It appears that anything within the cwd is iterated through, not just the expanded src matches.

        files: [{
            expand: true,
            cwd: "app/assets/stylesheets",
            src: [
                "modules/**/*.{scss,sass}",
                "partials/**/*.{scss,sass}",
                "sections/**/*.{scss,sass}"
            ],
            dest: "public/styleguide/"
        }]

gulp.js support

I know, I know. But it is really cool and I'd love to use sassdown with it.

Iframe height=0

One of the last commits broke the iframe height detection for some elements.
Probably this is caused by #65.

Also these changes were added to the same npm version. Better would be to release 0.2.7 or 0.3.0 ;)

[Feature] Remove iframe

Hey! Totally digging this plugin and I have a few suggestions. Would love to know your reasoning for the same.

  1. Remove iframe - it feels very odd to work with iframe. I remember you telling me this was so that styles and scripts don't leak. My use case is just for CSS. Theme CSS can be namespaced with .theme or something so that it doesn't interfere with styleguide CSS.
    It helps to see how the CSS is shaping up while working on it.
  2. I want to exclude folders from being output - is there an option for this already?
    My scss is as follows and I want to output only _buttons.scss
root
 - button
 -- _mixins.scss
 -- _extends.scss
 -- _buttons.scss
 -- _variables.scss

intendation "rules" unclear

I recently tried to get sassdown running, and was wondering why the iframe wasn't created.
For example, it failed with

/*

Alerts
======

Creates an alert box notification using the `.alert-` prefix. The following options are available:

  <p class="alert-success">Winning</p>
  <p class="alert-warning">Steady</p>
  <p class="alert-error">Oh Shit!</p>

*/

@mixin alert($colour){
  color: darken($colour, 50%);
  background: $colour;
  border-radius: 5px;
  margin-bottom: 1.2em;
  padding: 1em;
}

.alert-success { @include alert(#e2f3c1) }
.alert-warning { @include alert(#fceabe) }
.alert-error   { @include alert(#ffdcdc) }

The code seemed perfectly valid to me, but I found that when using only one tab for intendation, the markup snipped wasn't recognized. Only after adding a second one, sassdown did its magic ;)

Maybe you could add this to the documentation? Or even allow a single tab for intendation?

Unable to nest markdown in comments.

Working on documenting within comments and noticed a problem with rendering.

<div class="twelve sample">Twelve Columns</div>

Works just fine, but if I try to do

<div class="row">
<div class="twelve sample">Twelve Columns</div>
</div>

I see the wrapping div rendered as text in my styleguide, it doesn't compile to HTML. Here's a screenshot.

screen shot 2015-02-12 at 2 27 04 pm

Rendering code blocks

First of all, thanks for this awesome plugin. It's everything I wanted. I have a question and maybe they are already solved but I'll ask anyway

  1. How do you render code blocks AND have them show up as code?
    In my SCSS, I have the ocde to create badges like below. Currently, only the code is showing up. However, I'd like to also render this html so that the badges show up with different variations. Is this possible by editing the template?
    <span class="badge.badge-primary">
    <span class="badge.badge-secondary">
    <span class="badge.badge-alert">
    <span class="badge.badge-info">
    <span class="badge.badge-success">
    <span class="badge.badge-warning">

generate ids of iframes and scripts based on a content hash rather than randomly

Currently, the ids of iframes and scripts are generated randomly:
id: Math.random().toString(36).substr(2,5)
This means when the styleguide is generated, a lot of changes will appear in a git history even though no scss file has been modified between two runs.
Would it be possible to generates these ids from a hash of the content, so that unchanged scss files generate identical styleguides?

thanks!

Print sass variables

Hello,

I don't know if thats technically possible, but it would be reeeally cool if I could "print " variables in my comments. I can't do that with Sass alone because comments are not compiled.

What I want to use is the following
/*
# Test
Use #{$buttonClass} for a button. The primary color is #{$colorPrimary}
*/

Greetings

Main partial title not always applied to navigation dropdown

The first comment block in the Sass partial is used to denote the <h1> for the style guide page.

If a blank line is added after the opening comment block like so...

/*

My Module
=========
*/

...then the <h1> title is used in the dropdown navigation rather than the Sass partial name i.e. My Module appears in the navigation rather than _my-module.

However if that extra blank line is not added after the opening comment block e.g.

/*
My Module
=========
*/

then the Sass partial name is not replaced by this title and remains as the Sass partial name.

I think zero, one or many blank lines should be permissible in the opening comment block before the title.

iframe ID's. default vs template

When using sassdown without custom template enabled, the iframe ID's generate a random ID like: iframe_abcde , but when I use the latest template.hbs It creates numerical ID's like: iframe0, iframe1, etc.. Is the former meant to prevent caching, because I do have some browser caching issues using Firefox.

does not work with Sass syntax comments

given the following comment:

/*
 * Headings
 * ==========
 *
 * Headings examples ranging from H1-H4.
 *
 *  <h1>Heading 1</h1>
 *  <h2>Heading 2</h2>
 *  <h3>Heading 3</h3>
 *  <h4>Heading 4</h4>
 */

I expect the output to be

Headings

Headings examples ranging from H1-H4.

<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>

Instead, the output is:

  • Headings
  • ========== *
  • Headings examples ranging from H1-H4. *
  • Heading 1

  • Heading 2

  • Heading 3

  • Heading 4

The rendered HTML:

<div class="comment">
  <ul>
    <li>Headings</li>
    <li>==========*</li>
    <li>Headings examples ranging from H1-H4.*</li>
    <li>&lt;h1&gt;Heading 1&lt;/h1&gt;</li>
    <li>&lt;h2&gt;Heading 2&lt;/h2&gt;</li>
    <li>&lt;h3&gt;Heading 3&lt;/h3&gt;</li>
    <li>&lt;h4&gt;Heading 4&lt;/h4&gt;</li>
  </ul>
</div>

any thoughts on how to remedy this?

Feature Request: YAML front-matter syntax to extend Page Object

Sorry for the second feature request in this week. Like to share my thought...

This time, it is a feature I saw on the trulia/hologram styleguide repository. They use YAML front-matter syntax to specify vars or custom metadata.

YAML front matter is quite popular, read more:

Think of this optional section that is placed at the beginning of an documentation block. It is for optional metadata that will be extend the Page Object in some way.
Goal is to access this variable section somewhere in the handlebar templates.

In this Example you define metadata for the iframe context in the template.hbs.
I would be cool if it's possible to extend the generated iframe with this parameters.

/*

---
body_class: article
assets:
 - public/styleguide/article_styles.css

---

Alerts
======

Creates an alert box notification using the `.alert-` prefix. The following options are available:

    <div class="alert-success">Success</div> 
    <div class="alert-warning">Warning</div> 
    <div class="alert-error">Error</div>

*/

This then can be parsed with something like this. (I am a handlebar noob)
Hope you can guess the wanted result. Want to filter the inclusion of specific assest and define a custom body class attribute.

<html>
    <head>
        <!-- use result.assets if any otherwise global assets -->
        {{> assets ||= result.assets}}'
    </head>
    <body class="{{result.meta.body_class}}">
        {{result}}
    </body>
</html>

What do you think? :]

Greets,
m5o

Navigation should not be a list of nested conditionals

Navigation implementation is currently too verbose, which makes modifying template output difficult.

    <div id="nav">
        <h1><a href="{{> root}}/{{href}}">Styleguide</a></h1>
        {{#each pages}}
            {{#if isDirectory}}
                <h2 class="heading">{{name}}</h2>
                <ul class="group">
                {{#each pages}}
                    <li>
                        {{#if isDirectory}}
                            <h3 class="heading">{{name}}</h3>
                            <ul class="group">
                            {{#each pages}}
                                <li>
                                    {{#if isDirectory}}
                                        <h4 class="heading">{{name}}</h4>
                                        <ul class="group">
                                        {{#each pages}}
                                            <li>
                                                <a href="{{> root}}/{{href}}">{{title}}</a>
                                            </li>
                                        {{/each}}
                                        </ul>
                                    {{else}}
                                        <a href="{{> root}}/{{href}}">{{title}}</a>
                                    {{/if}}
                                </li>
                            {{/each}}
                            </ul>
                        {{else}}
                            <a href="{{> root}}/{{href}}">{{title}}</a>
                        {{/if}}
                    </li>
                {{/each}}
                </ul>
            {{else}}
                <a href="{{> root}}/{{href}}">{{title}}</a>
            {{/if}}
        {{/each}}
    </div>

Consider reducing necessary code or building an iterative loop that outputs into a single partial, such as {{> navigation}}, or a group of partials. Look into iteration in native Handlebars or explore pre-compiled options with nodejs.

Reduce repetition and duplication in the Config object

Currently the Config object is large contains severe duplication/repetition with the File object. See #24.

{
    opts: {
        readme: false,
        theme: 'tasks/data/theme.css',
        template: 'tasks/data/template.hbs',
        baseUrl: null,
        excludeMissing: true,
        commentStart: /\/\* (?:[=]{4,}\n[ ]+|(?!\n))/,
        commentEnd: /[ ]+[=]{4,} \*\//,
        assets: ['test/custom/assets/css/*.css']
    },
    files: [Object], // full list of all File objects
    groups: {
        base: {
            name: 'base',
            pages: [{
                heading: 'Base Styles',
                group: 'base',
                path: 'test/custom/styleguide/base/_base.html',
                url: '/test/custom/styleguide/base/_base.html'
            }]
        },
        modules: {
            name: 'modules',
            pages: [{
                heading: 'Media Object',
                group: 'modules',
                path: 'test/custom/styleguide/modules/_media.html',
                url: '/test/custom/styleguide/modules/_media.html'
            }]
        }
    },
    module: '/Users/hillsj/Sites/sassdown/tasks/sassdown.js',
    template: {
        html: [Function],
        assets: null
    },
    root: 'test/custom/assets',
    tree: {
        name: 'sass',
        path: 'test/custom/assets/sass',
        type: 'dir',
        data: {},
        children: [{
            name: 'application.sass',
            path: 'test/custom/assets/sass/application.sass',
            type: 'file',
            data: {}
        }, {
            name: 'base',
            path: 'test/custom/assets/sass/base',
            type: 'dir',
            data: {},
            children: [{
                name: '_base.sass',
                path: 'test/custom/assets/sass/base/_base.sass',
                type: 'file',
                data: [Object] // contains File object
            }]
        }, {
            name: 'modules',
            path: 'test/custom/assets/sass/modules',
            type: 'dir',
            data: {},
            children: [{
                name: '_media.sass',
                path: 'test/custom/assets/sass/modules/_media.sass',
                type: 'file',
                data: [Object] // contains File object
            }]
        }]
    }
}

Empty files object returns cryptic error message

Copied from pull request #78 in case this isn't the correct fix:

If the files array doesn't resolve anything, sassdown returns Warning: Cannot read property 'orig' of undefined Use --force to continue. Which tells the user very little.

To reproduce, change line 50 in Gruntfile.js to something like cwd: 'test/example/asses/sass/foo' and run grunt sassdown.

Result output should not contain or require any logic

In order to reduce style conflicts and safely sandbox elements, examples currently render into an iframe. This process is slightly complicated by the need to preserve indentation, linebreaks, whitespace and syntax highlighting.

We do this by writing the {{ result }} into a script element, then inserting that innerHTML into the iframe before removing the placeholder nodes from the DOM. This is messy and can be abstracted out of the actual .hbs file.

Current:

{{#if comment}}
    <div class="comment">{{{comment}}}</div>
{{/if}}
{{#if result}}
    <div class="result">
        <iframe id="iframe{{@index}}" height="0" src="about:blank"></iframe>
        <script id="result{{@index}}" type="text/html">{{{result}}}</script>
        <script id="script{{@index}}">
            var iframe  = document.getElementById('iframe{{@index}}');
            var script  = document.getElementById('script{{@index}}');
            var result  = document.getElementById('result{{@index}}');
            var context = iframe.contentWindow.document;
                context.open();
                context.write('<!DOCTYPE html>');
                context.write('<'+'html>');
                context.write('    <'+'head>');
                context.write('        {{> assets}}');
                context.write('    <'+'/'+'head>');
                context.write('    <'+'body>');
                context.write(result.innerHTML);
                context.write('    <'+'/'+'body>');
                context.write('<'+'/'+'html>');
                context.close();
            iframe.removeAttribute('id')
            result.parentNode.removeChild(result);
            script.parentNode.removeChild(script);
        </script>
    </div>
{{/if}}
{{#if markup}}
    <div class="markup">{{{markup}}}</div>
{{/if}}
{{#if styles}}
    <div class="styles">{{{styles}}}</div>
{{/if}}

Desired:

{{#if comment}}
    <div class="comment">{{{comment}}}</div>
{{/if}}
{{#if result}}
    <div class="result">{{{result}}}</div>
{{/if}}
{{#if markup}}
    <div class="markup">{{{markup}}}</div>
{{/if}}
{{#if styles}}
    <div class="styles">{{{styles}}}</div>
{{/if}}

Build a proper object for file tree structure

Currently, the config.tree is a hack as it contains both File objects (which contain config.tree, creating a circular). In order to reduce complexity, we could combine the two and store all File data within a tree object.

Related: #23

Output how html will look

Is it possible to output how ie. a button would look โ€“ along with the raw html?

My grunt task looks like this:


sassdown: {
    options: {
        assets: ['.tmp/styles/_.css']
    },
    files: {
        expand: true,
                cwd: 'src/styles',
                src: ['_.scss'],
                dest: '.tmp/styleguide/'
    }
}

Feature Request: Multi-line descriptions / Loop

First, this project is amazing!! The last weeks i played with different styleguide tools (grunt-styleguide, kss-node, styledocco). I am so happy that i found this repository.

On my testing trip I found one key feature from kss-node very interesting. Read the part on Multi-line descriptions.

In short - in their markup section they use the {$modifiers} keyword as a spacer. The next few lines specify the attributes. The syntax is like a list.

This is a example from the kss-node/demo

// Buttons
//
// A majority of buttons in the site are built from the same base class.
// 
// Markup:
// <a href="#" class="button {$modifiers}">Link Button</a>
// <button class="button {$modifiers}">Button Element</button>
// <input type="button" class="button {$modifiers}" value="input[type='button']"/>
// 
// .primary             - Indicate that the button is the primary feature of this form.
// .remove              - Indicate that the button will remove a feature, or other negative connotations.
// :hover               - Highlight the button when hovered.
// :disabled            - Make the button change appearance to reflect it being disabled.
// :active              - "Press" the button down when clicked.

The processor loops thought the markup code and add the attributes for $modifiers.

View the result It is cleaner, less duplication and easy to see different variations of an element.

or watch this kss-node-template with more multi-line descriptions and examples.

What do you think about this feature?
This is an open discussion. Is this possible with handlebars? Useful / Useless...

Greets,
m5o

Assets folder path resolves with back slashes in Handlebars template

The template.hbs file uses a variable to store the path to the assets folder - the parent folder of the CSS and JavaScript files (see below)

image

This {{site.assets}} variable resolves with backslashes rather than forward slashes which causes problems with some browsers on a Windows platform. For example Firefox cannot resolve the file path with a mixture of back and forward slashes - it requires forward slashes to be used.

See screen grab below from the Chrome Dev Tools Inspector for how the above file paths actually resolve.

image

Publish a bugfix to registry

Hi,

a colleague of mine came across the problem that, when not using assets, 0.2.6 throws the following error:

Running "sassdown:styleguide" (sassdown) task
Warning: Cannot call method 'forEach' of undefined Use --force to continue.
TypeError: Cannot call method 'forEach' of undefined
    at Object.module.exports.writeOut (/Users/marcdix/projects/node/tests/sassdown/node_modules/sassdown/tasks/libs/sassdown.js:329:28)
    at Object.module.exports.readme (/Users/marcdix/projects/node/tests/sassdown/node_modules/sassdown/tasks/libs/sassdown.js:247:14)
    at Object.<anonymous> (/Users/marcdix/projects/node/tests/sassdown/node_modules/sassdown/tasks/sassdown.js:58:18)
    at Object.<anonymous> (/Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/grunt/task.js:264:15)
    at Object.thisTask.fn (/Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/grunt/task.js:82:16)
    at Object.<anonymous> (/Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/util/task.js:301:30)
    at Task.runTaskFn (/Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/util/task.js:251:24)
    at Task.<anonymous> (/Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/util/task.js:300:12)
    at /Users/marcdix/projects/node/tests/sassdown/node_modules/grunt/lib/util/task.js:227:11
    at process._tickCallback (node.js:419:13)

Aborted due to warnings.

This is caused by a missing check in lib/sassdown.js before looping Sassdown.config.assets which might be undefined at that point.

This check has already been added to the current master branch but not published to the npm registry yet, so I'd suggest either publishing a new version (if applicable) or publishing a bugfix as 0.2.7 to the registry.

With the current version of Sassdown, when not specifing assets in the Grunt-Options even the examples from Readme.md will not work when installing Sassdown via npm install sassdown --save-dev.


Others: If you need this plugin badly, add the repository instead of the version to your package.json. By doing so, you bypass the registry and install the latest latest latest Sassdown directly from github. Please bear in mind to drop in now and then to check if it's fixed an replace it by the version as it's no good practice to use the repo directly.*

  "devDependencies": {
    "sassdown": "git://github.com/nopr/sassdown.git#master"
  }

Best
Marc

Preformatted Code Lines

Hi!

First of all: nice plugin!

Would be even nicer if I could use the <pre> element with new lines.

I have these lines in my comment (surrounded with three `):

<pre><code>function getJelly() {
    echo $aDeliciousSnack;
}</code></pre>

but the code output is this:

<pre><code>function getJelly() { echo $aDeliciousSnack;}</code></pre>

Am I doing something wrong? Is it a bug?

Make code block output clearer and cleaner

By parsing code through Prism before compiling the template (#22), we can significantly reduce the required markup. We can also differentiate between sources further by renaming to markup and source, rather than source and cssSource (as it may not always be CSS).

{{#if source}}
    <div class="source language-markup" data-source-type="html">
        {{{source}}}
    </div>
{{/if}}
{{#if cssSource}}
    <div class="source language-{{prismLang}}" data-source-type="{{fileExt}}">
        {{{cssSource}}}
    </div>
{{/if}}

Assets folder path resolves with back slashes in Handlebars template

The template.hbs file uses a variable to store the path to the assets folder - the parent folder of the CSS and JavaScript files (see below)

image

This {{site.assets}} variable resolves with backslashes rather than forward slashes which causes problems with some browsers on a Windows platform. For example Firefox cannot resolve the file path with a mixture of back and forward slashes - it requires forward slashes to be used.

See screen grab below from the Chrome Dev Tools Inspector for how the above file paths actually resolve.

image

Feature Request: Development mode

Would it be possible include a developer mode to associate the line numbers and file to a given section where by the developer could click on the MD/Scss and save back to the file or revert the changes they've just made?

This would open it up to other tasks to watch for edits, compile and live reload the style guide so developers could make amends a lot quicker.

Structure of assets and styleguide

Trying to figure out, how to structure files and styleguide. Correct me if i'm wrong.

So, know we use files as a base for our structure for styleguide. First-level folders become our main menu items in styleguide, and all the files in this first-level folders - parts of a dropdown, second level?

Or can we alter this somehow (i don't know if i need this, just asking)? Say, something like "This two files buttons1.scss and buttons2.scss must be in part "buttons" of a styleguide".

Provide a way to add scripts at the bottom of the body

It could be really useful to be able to output scripts at the bottom of the body. Doing so make it unnecessary to add $(document).ready.. to each scripts.

On my setup I quickly fixed it by splitting the localAssets in the writeOut function and added 2 helpers (scripts and styles). Now I think it would be better to add an option footerAssets just like assets. This would be more flexible and would add less complexity.

What do you think?

Make styleguide navigation easier to create

Current method of writing out navigation structures is unwieldy and obtuse, using three custom helpers.

<div class="navigation">
    <div class="gutter">
        <div class="group {{#if_group ''}}is-active{{/if_group}}">
            <a href="{{ page.site.rootUrl }}">Home</a>
        </div>
        {{#each page.site.groups}}
        <div class="group {{#if_name ../group}}is-active{{/if_name}}">
            <span>{{ name }}</span>
            <ul>
                {{#each pages}}
                <li><a class="{{#if_path ../../path}}is-active{{/if_path}}" href="{{ url }}">{{ heading }}</a></li>
                {{/each}}
            </ul>
        </div>
        {{/each}}
    </div>
</div>

Page Navigation Item Name will be overwritten

fetched the latest version 0.2.6. Here are some example file, covered the bug.

assets/stylesheets/partials/_alerts.scss:

/*

# Alerts

basic stuff

    <div class="alert">alert</div> 

*/
.alert {
  border: 1px solid;
}



/*

# Alert Colors

color stuff

    <div class="alert alert-danger">alert</div> 

*/
.alert-danger {
  border-color: red;
}

The Stylesheet generation is fine. The Title in the Navigation will be overwritten with the last h1 in the markdown. So in this example Alert Colors is the Title, not Alerts. This is different to the previous version.

I would suggest an fictitious nopr/sassdown-example repo. Maybe a Rails app, pushed to heroku (free) to test and see the current released version under real conditions. I'll contribute to this if you give me the push rights to the example repo.

fails to compile .hbs properly?

I've just pushed the latest code to my repo - https://github.com/sturobson/Squeeler

when compiling and watching (look at _alerts.scss for the example) I get this error

' +''); context.close(); script.parentNode.removeChild(script);

after the iframe in the results div with a script id of "script_ioedk". I've completely restarted the npm install stuff, deleting anything that's pulled down and started it again. But this still happens.

Any ideas?

Navigation should automatically reflect the currently active page

Related to #48 and #46

Navigation items and menus should reflect the current page that is open. Whether that is through a Handlebars conditional (eg. {{#if isActive}}) or native nodejs solution before compiling the template. The latter would probably be best, to reduce the amount of markup and logic needed to write a template file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.