diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..899140f9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# This file is used by editors and IDEs to unify coding standards +# @see http://EditorConfig.org +# @standards PHP: http://www.php-fig.org/psr/psr-2/ +root = true + +# Default configuration (applies to all file types) +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_size = 4 +indent_style = space + +[*.{css,js,vue}] +indent_size = 2 + +# Markdown customizations +[*.md] +trim_trailing_whitespace = false diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..d55a3754 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +module.exports = { + 'env': { + 'browser': true, + 'es6': true, + "node": true + }, + 'extends': [ + 'eslint:recommended', + 'plugin:vue/recommended' + ], + 'plugins': [ + 'vue' + ] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..108f6b2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/bin/ +/node_modules/ +/output_*/ +/source/build/ +/vendor/ +/.phpunit.result.cache diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 00000000..218c1a41 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,14 @@ +files()->in(['src', 'tests']); + +return Config::create() + ->setRules([ + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + ]) + ->setFinder($finder); diff --git a/app/SculpinKernel.php b/app/SculpinKernel.php new file mode 100644 index 00000000..eb89ff70 --- /dev/null +++ b/app/SculpinKernel.php @@ -0,0 +1,21 @@ + *:not(:first-child) { + @apply mt-6 + } + + p a { + @apply text-black underline; + + &:hover { + @apply no-underline + } + } +} diff --git a/assets/css/components/table.pcss b/assets/css/components/table.pcss new file mode 100644 index 00000000..24c8bc19 --- /dev/null +++ b/assets/css/components/table.pcss @@ -0,0 +1,18 @@ +.table { + @apply w-full; + + th { + @apply bg-gray-200 text-left + } + + th, + td { + @apply px-4 py-2 border border-solid border-gray-300 + } +} + +table.is-striped { + tbody > tr:not(:nth-child(odd)) td { + @apply bg-gray-100 + } +} diff --git a/assets/css/components/video.pcss b/assets/css/components/video.pcss new file mode 100644 index 00000000..b03da98f --- /dev/null +++ b/assets/css/components/video.pcss @@ -0,0 +1,9 @@ +.video-full { + @apply w-full relative; + padding-top: 56.25%; + + iframe, + embed { + @apply absolute h-full left-0 top-0 w-full + } +} diff --git a/assets/css/components/widget.pcss b/assets/css/components/widget.pcss new file mode 100644 index 00000000..fdcc356b --- /dev/null +++ b/assets/css/components/widget.pcss @@ -0,0 +1,3 @@ +.widget { + @apply block mb-6 +} diff --git a/assets/css/components/wrap.pcss b/assets/css/components/wrap.pcss new file mode 100644 index 00000000..9fe5fde9 --- /dev/null +++ b/assets/css/components/wrap.pcss @@ -0,0 +1,7 @@ +.wrap { + @apply w-full max-w-3xl mx-auto; + + &.is-wide { + @apply max-w-5xl + } +} diff --git a/assets/css/custom-base.pcss b/assets/css/custom-base.pcss new file mode 100644 index 00000000..631edccb --- /dev/null +++ b/assets/css/custom-base.pcss @@ -0,0 +1,27 @@ +h1, h2, h3 { + @apply font-bold +} + +h1 { + @apply text-3xl +} + +h2 { + @apply text-2xl +} + +img { + @apply max-w-full h-auto +} + +a { + @apply text-blue-700 no-underline; + + &:hover { + @apply underline + } +} + +blockquote { + @apply pl-5 border-l-4 border-gray-300 italic +} diff --git a/assets/css/custom-components.pcss b/assets/css/custom-components.pcss new file mode 100644 index 00000000..f37bc5e4 --- /dev/null +++ b/assets/css/custom-components.pcss @@ -0,0 +1,9 @@ +@import './components/button.pcss'; +@import './components/container.pcss'; +@import './components/lead.pcss'; +@import './components/markup.pcss'; +@import './components/note.pcss'; +@import './components/table.pcss'; +@import './components/video.pcss'; +@import './components/widget.pcss'; +@import './components/wrap.pcss'; diff --git a/assets/css/custom-utilities.pcss b/assets/css/custom-utilities.pcss new file mode 100644 index 00000000..e39fd278 --- /dev/null +++ b/assets/css/custom-utilities.pcss @@ -0,0 +1,3 @@ +.no-js .js-hidden { + display: none +} diff --git a/assets/css/libraries/hljs.pcss b/assets/css/libraries/hljs.pcss new file mode 100644 index 00000000..4cf71ae2 --- /dev/null +++ b/assets/css/libraries/hljs.pcss @@ -0,0 +1,3 @@ +.hljs { + @apply p-0 bg-inherit +} diff --git a/assets/js/app.js b/assets/js/app.js new file mode 100644 index 00000000..53499990 --- /dev/null +++ b/assets/js/app.js @@ -0,0 +1,11 @@ +import 'alpinejs' +import '../css/app.pcss' +import turbolinks from 'turbolinks' + +window.hljs = require('highlightjs') + +let html = document.documentElement +html.classList.remove('no-js') +html.classList.add('js') + +turbolinks.start() diff --git a/assets/js/vendor/gist-embed.js b/assets/js/vendor/gist-embed.js new file mode 100644 index 00000000..d4c54a65 --- /dev/null +++ b/assets/js/vendor/gist-embed.js @@ -0,0 +1,199 @@ +/* + * author: Blair Vanderhoof + * https://github.com/blairvanderhoof/gist-embed + * version 2.4 + */ +(function($) { + 'use strict'; + + function getLineNumbers(lineRangeString) { + var lineNumbers = [], range, lineNumberSections; + + if (typeof lineRangeString === 'number') { + lineNumbers.push(lineRangeString); + } else { + lineNumberSections = lineRangeString.split(','); + + for (var i = 0; i < lineNumberSections.length; i++) { + range = lineNumberSections[i].split('-'); + if (range.length === 2) { + for (var j = parseInt(range[0], 10); j <= range[1]; j++) { + lineNumbers.push(j); + } + } else if (range.length === 1) { + lineNumbers.push(parseInt(range[0], 10)); + } + } + } + return lineNumbers; + } + + $.fn.gist = function() { + return this.each(function() { + var $elem = $(this), + id, + url, + file, + lines, + loading, + highlightLines, + hideFooterOption, + hideLineNumbersOption, + showLoading, + showSpinner, + data = {}; + + // make block level so loading text shows properly + $elem.css('display', 'block'); + + id = $elem.data('gist-id') || ''; + file = $elem.data('gist-file'); + hideFooterOption = $elem.data('gist-hide-footer') === true; + hideLineNumbersOption = $elem.data('gist-hide-line-numbers') === true; + lines = $elem.data('gist-line'); + highlightLines = $elem.data('gist-highlight-line'); + showSpinner = $elem.data('gist-show-spinner') === true; + if (showSpinner) { + showLoading = false; + } else { + showLoading = $elem.data('gist-show-loading') !== undefined ? + $elem.data('gist-show-loading') : true; + } + + if (file) { + data.file = file; + } + + // if the id doesn't exist, then ignore the code block + if (!id) { + return false; + } + + url = 'https://gist.github.com/' + id + '.json'; + loading = 'Loading gist ' + url + (data.file ? ', file: ' + data.file : '') + '...'; + + // loading + if (showLoading) { + $elem.html(loading); + } + + // loading spinner + if (showSpinner) { + $elem.html('' + loading + ''); + } + + // request the json version of this gist + $.ajax({ + url: url, + data: data, + dataType: 'jsonp', + timeout: 10000, + success: function(response) { + var linkTag, + head, + lineNumbers, + highlightLineNumbers, + $responseDiv; + + // the html payload is in the div property + if (response && response.div) { + // github returns /assets/embed-id.css now, but let's be sure about that + if (response.stylesheet) { + // github passes down html instead of a url for the stylehsheet now + // parse off the href + if (response.stylesheet.indexOf('