Merge pull request #55 from rstacruz/feature/2017-layout

New layout
This commit is contained in:
Rico Sta. Cruz 2017-08-28 00:03:50 +08:00 committed by GitHub
commit cc50f69236
41 changed files with 4988 additions and 1060 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
_output _output
_site _site
.jekyll-metadata

View File

@ -1 +1,38 @@
:) :)
---
## Notes
`h2` supports these:
{: .-two-column}
{: .-three-column}
{: .-left-reference}
`h3` supports these:
{: .-prime}
`table` supports these:
{: .-shortcuts}
`pre` supports these:
{: .-setup}
`ul` supports these:
{: .-also-see}
Each sheet supports these metadata:
```yml
---
title: React.js
category: React
layout: 2017/sheet # 'default' | '2017/sheet'
ads: true # Add this for ads
---
```

View File

@ -9,7 +9,7 @@ exclude:
- _deprecated - _deprecated
# Markdown # Markdown
highlighter: rouge highlighter: false
markdown: kramdown markdown: kramdown
kramdown: kramdown:
input: GFM input: GFM

2
_includes/2017/foot.html Normal file
View File

@ -0,0 +1,2 @@
</body>
</html>

26
_includes/2017/head.html Normal file
View File

@ -0,0 +1,26 @@
<!doctype html>
<html lang='en' class='no-js {{ page.html_class }}'>
<head>
{% include meta.html %}
{% include polyfills.html %}
<!-- 3rd-party libs -->
<script src='https://code.jquery.com/jquery-3.1.0.js'></script>
<script src='https://unpkg.com/isotope-layout@3.0.4/dist/isotope.pkgd.min.js'></script>
<script src='https://unpkg.com/prismjs@1.6.0'></script>
<script src='https://unpkg.com/prismjs@1.6.0/components/prism-jsx.min.js'></script>
<script src='https://unpkg.com/prismjs@1.6.0/components/prism-bash.min.js'></script>
<script src='https://unpkg.com/prismjs@1.6.0/components/prism-scss.min.js'></script>
<script src='https://unpkg.com/prismjs@1.6.0/components/prism-elixir.min.js'></script>
<script src='https://unpkg.com/prismjs@1.6.0/plugins/line-highlight/prism-line-highlight.min.js'></script>
<link rel='stylesheet' href='https://unpkg.com/sanitize.css@5.0.0/sanitize.css'>
<!-- <link rel='stylesheet' href='https://unpkg.com/prismjs@1.6.0/themes/prism.css'> -->
<link rel='stylesheet' href='https://unpkg.com/prismjs@1.6.0/plugins/line-highlight/prism-line-highlight.css'>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Fira+Code:400'>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:300,400,700'>
<!-- 2017 layout -->
<link href='{{base}}/assets/2017/style.css?t={{ timestamp }}' rel='stylesheet'>
<script src='{{base}}/assets/2017/script.js?t={{ timestamp }}'></script>
</head>
<body>

View File

@ -0,0 +1,18 @@
<div class='top-nav'>
<div class='container'>
<a class='brand' href='{{base}}'>
Rico's cheatsheets
</a>
<div class='actions'>
{% include social-list.html class="social page-actions" page=include.page %}
<ul class='page-actions'>
<li class='link github -button hint--bottom' data-hint='Edit this page on GitHub'>
<a href='https://github.com/rstacruz/cheatsheets/blob/gh-pages/{{ page.path | remove: '.html' }}'>
<span class='text -visible'>Edit</span>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -1,6 +1,6 @@
{% assign description = "The ultimate cheatsheet for " | append: include.page.title | append: "." %} {% assign description = "The ultimate cheatsheet for " | append: include.page.title | append: "." %}
<ul class="social-list {{ include.class }}"> <ul class="social-list {{ include.class }}">
<li class="facebook hint--bottom" data-hint="Share on Facebook"><a href="https://www.facebook.com/sharer/sharer.php?u={{ site.url }}{{ include.page.url }}" target="share"><span class="text">Like</span></a></li> <li class="facebook link hint--bottom" data-hint="Share on Facebook"><a href="https://www.facebook.com/sharer/sharer.php?u={{ site.url }}{{ include.page.url }}" target="share"><span class="text">Like</span></a></li>
<li class="twitter hint--bottom" data-hint="Share on Twitter"><a href="https://twitter.com/intent/tweet?text={{ description }} {{ site.url }}{{ include.page.url }}" target="share"><span class="text">Tweet</span></a></li> <li class="twitter link hint--bottom" data-hint="Share on Twitter"><a href="https://twitter.com/intent/tweet?text={{ description }} {{ site.url }}{{ include.page.url }}" target="share"><span class="text">Tweet</span></a></li>
<li class="googleplus hint--bottom" data-hint="Share on Google Plus"><a href="https://plus.google.com/share?url={{ site.url }}{{ include.page.url }}" target="share"><span class="text">+1</span></a></li> <!--<li class="googleplus link hint--bottom" data-hint="Share on Google Plus"><a href="https://plus.google.com/share?url={{ site.url }}{{ include.page.url }}" target="share"><span class="text">+1</span></a></li>-->
</ul> </ul>

23
_layouts/2017/sheet.html Normal file
View File

@ -0,0 +1,23 @@
---
type: article
---
{% include 2017/head.html %}
{% include 2017/top-nav.html page=page %}
<div class='body-area'>
<div class='main-heading {% if page.ads %}-with-ads{% endif %}'>
<h1 class='h1'>{{ page.title }} <em>cheatsheet</em></h1>
{% if page.ads %}
<div class='HeadlineAd ad'>
<script async src='//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=ricostacruzcom' id="_carbonads_js"></script>
</div>
{% endif %}
</div>
<div class='post-content MarkdownBody' data-js-main-body>
{{ content }}
</div>
</div>
{% include 2017/foot.html %}

55
_sass/2017/base/base.scss Normal file
View File

@ -0,0 +1,55 @@
/*
* Base
*/
html, body {
background: $base-body;
font-family: $body-font;
font-size: 14px;
line-height: 1.6;
color: $base-text;
}
body {
@include font-size(0);
padding: 0;
margin: 0;
}
/*
* Code
*/
pre, code {
font-family: $monospace-font;
letter-spacing: -0.03em;
}
pre {
font-size: 0.92em;
}
/*
* Antialias
*/
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/*
* Links
*/
a {
color: $base-b;
}
a:visited {
color: $base-b7;
}
a:hover {
color: $base-b3;
}

View File

@ -0,0 +1,5 @@
.body-area {
max-width: $area-width;
margin: 0 auto;
@include gutter(padding);
}

View File

@ -0,0 +1,16 @@
/*
* h2 section
*/
/* Hide the first h2 heading */
.h2-section {
&:first-child > h2 {
display: none;
}
@media (min-width: 481px) {
& + & {
margin-top: 32px;
}
}
}

View File

@ -0,0 +1,92 @@
/*
* H3 section list:
* The body that is isotoped.
*/
.h3-section-list {
& {
margin: 0 auto;
}
// Clearfix
&::after {
content: '';
display: table;
clear: both;
zoom: 1;
}
// Each section
& > .h3-section {
@include gutter(padding);
float: left;
width: 100%;
}
& > .h3-section {
padding-top: 0;
}
}
/*
* Two column (default)
*/
.h3-section-list,
.h3-section-list.-two-column {
@media (min-width: 769px) {
& > .h3-section {
width: 50%;
}
}
}
/*
* One column
*/
.h3-section-list.-one-column {
& > .h3-section {
width: 100%;
}
}
/*
* Three column
*/
.h3-section-list.-three-column {
@media (min-width: 769px) {
& > .h3-section {
width: 50%;
}
}
@media (min-width: 961px) {
& > .h3-section {
width: 33.33%;
}
}
}
/*
* Three column, left reference
*/
.h3-section-list.-left-reference {
@media (min-width: 769px) {
& > .h3-section {
width: 50%;
}
}
@media (min-width: 961px) {
& > .h3-section {
width: 66.67%;
}
& > .h3-section:first-child {
width: 33.33%;
}
}
}

View File

@ -0,0 +1,151 @@
/*
* H3 section
*/
.h3-section > .body {
& > pre {
margin: 0;
padding: 16px;
}
& {
background: white;
box-shadow: $shadow3;
}
/* Collapse/flush */
@media (max-width: 480px) {
margin: 0 -16px;
box-shadow: $shadow2;
}
/* Border radius */
@media (min-width: 481px) {
& {
border-radius: 2px;
}
& > :first-child {
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}
& > :last-child {
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}
}
}
/*
* Children
*/
.h3-section > .body {
/* Lists */
& > ul {
margin: 0;
padding: 0;
list-style-type: none;
}
& > ul > li {
padding: 8px;
padding-left: 32px + 4px;
position: relative;
}
& > ul > li::before {
content: '';
position: absolute;
display: inline-block;
width: 4px;
height: 4px;
background: $gray-text;
border-radius: 50%;
left: 16px;
top: 16px + 2px;
}
& > ul > li + li {
border-top: solid 1px $line-color;
}
/* Paragraphs */
& > p {
padding: 16px;
margin: 0;
}
/* Description paragraphs */
& > pre ~ p,
& > ul ~ p,
& > iframe ~ p,
& > table ~ p {
background: $gray-bg;
color: $gray-text;
/* Links */
& a,
& a:visited {
color: $base-text;
text-decoration: none;
border-bottom: solid 1px $line-color;
}
& a:hover {
color: $base-b;
}
}
/* Line divisions */
& > *:not(:first-child) {
border-top: solid 1px $line-color;
}
}
/*
* Prime
*/
.h3-section.-prime > .body {
@media (min-width: 481px) {
border-radius: 2px;
box-shadow: $shadow6;
}
}
ul.-also-see.-also-see.-also-see {
display: flex;
flex-wrap: wrap;
background: $gray-bg;
& > li {
flex: 1 0 20%;
padding: 24px;
border-top: solid 1px $dark-line-color;
& + li {
border-left: solid 1px $dark-line-color;
}
}
&,
& > li {
list-style-type: none;
}
& > li::before {
display: none;
}
& > li > a {
@include font-size(1);
display: block;
}
& > li > em {
@include font-size(-1);
display: block;
}
}

View File

@ -0,0 +1,79 @@
/*
* Carbon ads
*
* .headline-ad
* #carbonads
* span
* span.carbon-wrap
* a.carbon-img > img
* a.carbon-text {description}
* a.carbon-poweredby {powered by Carbon}
*/
.HeadlineAd {
@include font-size(-1);
& {
display: inline-block;
}
&,
& > div > span {
min-width: 130px + 16px + 64px;
max-width: 400px;
height: 100px;
}
& > div > span {
display: inline-block;
text-align: right;
}
& > div > span::after {
content: '';
display: table;
clear: both;
zoom: 1;
}
.carbon-img,
.carbon-text,
.carbon-poweredby {
text-decoration: none;
display: block;
}
.carbon-img {
float: right;
margin-left: 16px;
width: 130px;
height: 100px;
box-shadow: $shadow3;
}
.carbon-img > img {
border-radius: 3px;
background: white;
}
.carbon-img:hover {
transform: translate3d(0, -1px, 0);
box-shadow: $shadow6;
}
.carbon-text,
.carbon-text:visited {
color: $gray-text;
}
.carbon-poweredby,
.carbon-poweredby:visited {
color: lighten($gray-text, 20%);
}
.carbon-text:hover,
.carbon-poweredby:hover {
color: $base-a;
}
}

View File

@ -0,0 +1,68 @@
/*
* The top-level heading
*/
.main-heading {
@include heading-style;
& > h1 {
@include font-size(6);
line-height: 1.2;
font-weight: 300;
font-family: $body-font;
margin: 0;
}
& > h1 > em {
font-style: normal;
color: lighten($gray-text, 20%);
}
}
/*
* With ads
*/
.main-heading.-with-ads {
& {
display: flex;
}
// Desktop
@media (min-width: 541px) {
& {
align-items: flex-end; // bottom alighn
}
& > h1 {
flex: 1 0 auto;
}
// Advertisement
& > .ad {
flex: 0 1 auto;
}
}
@media (max-width: 540px) {
& {
flex-direction: column;
flex-wrap: wrap;
}
& > h1,
& > .ad {
flex: 1 0 100%;
}
& > h1 {
order: 2;
}
& > .ad {
order: 1;
margin-left: auto;
margin-bottom: 16px;
}
}
}

View File

@ -0,0 +1,79 @@
@mixin action-bar {
& {
height: 32px;
}
& > .link.link > a,
& > .link.link > a::before {
display: inline-block;
height: 32px;
line-height: 32px;
vertical-align: top;
width: auto;
}
& > .link.link > a {
padding: 0 8px;
}
&,
& > li {
margin: 0;
padding: 0;
list-style-type: none;
}
& > li > a,
& > li > a:visited {
color: $base-mute;
text-decoration: none;
}
& > li > a:hover,
& > li > a:focus {
color: $base-b3;
& > .text {
color: $base-b3;
}
}
& > li > a::before {
font-size: 16px;
text-align: center;
}
& > li > a > .text {
@include font-size(-1);
display: none;
}
& > li > a > .text.-visible {
display: inline;
}
}
.page-actions {
& {
@include action-bar;
}
& > .facebook > a::before {
@include ion-icon('logo-facebook');
}
& > .twitter > a::before {
@include ion-icon('logo-twitter');
}
& > .github > a::before {
@include ion-icon('logo-github');
}
& > .link.-button > a {
box-shadow: inset 0 0 0 1px $dark-line-color;
border-radius: 2px;
padding: 0 16px;
margin: 0 8px;
}
}

View File

@ -0,0 +1,54 @@
.top-nav {
& {
border-bottom: solid 1px $dark-line-color;
height: 48px;
line-height: 48px;
text-align: center;
}
>.container {
@include gutter(padding-left);
@include gutter(padding-right);
max-width: $area-width;
margin: 0 auto;
}
}
.top-nav > .container {
& {
display: flex;
align-items: center;
}
& > .brand {
flex: 1 1 auto;
}
& > .actions {
flex: 0 0 auto;
display: flex;
}
& > .brand {
@include font-size(-1);
display: inline-block;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.05em;
text-decoration: none;
&,
&:visited {
color: $base-text;
}
&:hover {
color: $base-a;
}
}
& > .actions > .social {
}
}
// page-actions.scss

View File

@ -0,0 +1,99 @@
.MarkdownBody code {
color: $gray-text;
font-size: 0.86em;
}
.MarkdownBody pre,
.MarkdownBody code {
font-family: $monospace-font;
}
/*
* Undo prism theme crap
*/
.MarkdownBody {
pre {
box-shadow: none;
border-left: 0;
overflow: hidden;
overflow-x: auto;
background: white;
}
pre > code {
color: $base-text;
max-height: auto;
padding: 0;
background: transparent;
overflow: visible;
font-size: 1em;
}
// Line highlight
.line-highlight {
transform: translate3d(0, 1px, 0);
background: linear-gradient(
to right,
rgba($base-c, 0.05) 25%,
rgba($base-c, 0));
}
// Line highlight ranges
.line-highlight[data-end] {
margin-top: 0;
}
.line-highlight::before,
.line-highlight::after {
display: none;
}
}
.MarkdownBody pre.-setup {
background: $gray-bg;
}
/*
* Syntax kighlight
*/
.token {
$cA: $base-b;
$cA-3: adjust-color($cA, $lightness: 15%, $hue: -10deg);
$cA-7: adjust-color($cA, $lightness: -15%, $hue: 10deg);
$cB: $base-c;
$cB-3: adjust-color($cB, $lightness: 15%, $hue: -10deg);
$cM: #aaa; // Mute
&.tag,
&.keyword {
color: $cA;
}
&.tag {
color: $cA-7;
}
&.value,
&.string,
&.number,
&.attr-value,
&.boolean,
&.regex {
color: $cB;
}
&.function,
&.attr-name {
color: $cA-3;
}
&.comment,
&.punctuation,
&.operator {
color: $cM;
}
}

View File

@ -0,0 +1,45 @@
/*
* MarkdownBody context
*/
.MarkdownBody h2 {
@include heading-style;
@include font-size(5);
line-height: 1.2;
font-weight: 300;
font-family: $heading-font;
margin-top: 0;
}
.MarkdownBody h3 {
margin: 0;
padding: 0;
margin-bottom: 16px;
font-family: $heading-font;
@include font-size(2);
font-weight: 300;
color: $base-a;
}
.MarkdownBody {
a,
a:visited {
color: $base-b;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
em {
font-style: normal;
color: $gray-text;
}
iframe {
border: 0;
margin: 0;
width: 100%;
}
}

View File

@ -0,0 +1,67 @@
/*
* Table
*/
.MarkdownBody table {
& {
width: 100%;
}
& tr + tr {
border-top: solid 1px $line-color;
}
/* Horizontal lines */
& tbody + tbody {
border-top: solid 1px $dark-line-color;
}
& td,
& th {
padding: 8px 16px;
vertical-align: top;
}
& tr td:last-child {
text-align: right;
}
& td:first-child {
white-space: nowrap;
}
& td:first-child > code {
font-size: 0.86em;
color: #35a;
}
& a,
& a:visited {
color: #35a;
text-decoration: none;
}
& td:first-child > code ~ em {
font-style: normal;
font-size: 0.86em;
color: $gray-text;
}
& thead {
display: none;
}
}
.MarkdownBody table.-shortcuts {
code {
font-size: 1em;
padding: 5px 6px;
padding-left: 8px; // compensation
background: $gray-bg;
border-radius: 3px;
margin-right: 2px;
letter-spacing: 0.2em;
font-family: $body-font;
color: $base-text;
}
}

20
_sass/2017/style.scss Normal file
View File

@ -0,0 +1,20 @@
@import url('https://unpkg.com/hint.css@2.5.0/hint.min.css');
@import './variables';
@import '../vendor/modularscale/modularscale';
@import '../vendor/iconfonts/ionicons@3';
@import './utils/font-size';
@import './utils/gutter';
@import './utils/heading-style';
@include ion-font;
@import './base/base';
@import './markdown/code';
@import './markdown/headings';
@import './markdown/table';
@import './components/body-area';
@import './components/h2-section';
@import './components/h3-section';
@import './components/h3-section-list';
@import './components/headline-ad';
@import './components/main-heading';
@import './components/page-actions';
@import './components/top-nav';

View File

@ -0,0 +1,3 @@
@mixin font-size ($n) {
@include ms-respond(font-size, $n);
}

View File

@ -0,0 +1,7 @@
@mixin gutter ($property, $multiplier: 1) {
#{$property}: $gut * $multiplier;
@media (max-width: 480px) {
#{$property}: $gut-small * $multiplier;
}
}

View File

@ -0,0 +1,22 @@
@mixin heading-style {
margin: $gut;
padding: 0;
margin-bottom: 16px + 8px;
padding-bottom: 16px + 8px;
margin-top: 64px;
border-bottom: solid 1px $dark-line-color;
@media (max-width: 768px) {
margin: $gut;
margin-bottom: 8px;
margin-top: 32px;
padding-bottom: 8px;
}
@media (max-width: 480px) {
margin: $gut-small;
margin-bottom: 8px;
margin-top: 32px;
padding-bottom: 8px;
}
}

72
_sass/2017/variables.scss Normal file
View File

@ -0,0 +1,72 @@
/*
* Metrics
*/
$gut-small: 8px; // max 480px width
$gut: 16px;
$column: 400px;
$area-width: $column * 3 + 32px;
/*
* Fonts
*/
$system-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
$body-font: 'Roboto', $system-font;
$heading-font: 'Roboto', $system-font;
$monospace-font: 'Fira Mono', Consolas, menlo, 'Andale Mono', 'Ubuntu Mono', monospace;
/*
* Base colors
*/
$base-body: #f1f3f5;
$base-panel: white;
$base-head: #111;
$base-text: #345;
$base-mute: #667788; // gray
$base-a: #8370bd; // indigo
$base-b: #2b72a2; // blue
$base-c: #17c694; // teal
$base-b3: adjust-color($base-b, $lightness: 16%, $hue: -20deg);
$base-b7: adjust-color($base-b, $lightness: -16%, $hue: 20deg);
$base-mute3: adjust-color($base-mute, $lightness: -16%);
$base-mute4: adjust-color($base-mute, $lightness: -8%);
$base-mute6: adjust-color($base-mute, $lightness: 8%);
$base-mute7: adjust-color($base-mute, $lightness: 16%);
$body-bg: $base-body;
$gray-bg: mix($base-body, $base-panel, 50%);
$gray-text: $base-mute;
$line-color: rgba($base-mute, 0.05);
$dark-line-color: rgba($base-mute, 0.14);
//
// Shadows
//
$shadow2:
0 1px 1px rgba($base-mute, 0.30);
$shadow3:
0 6px 8px rgba($base-mute, 0.02),
0 1px 2px rgba($base-mute, 0.20);
$shadow6:
0 8px 12px rgba($base-b3, 0.1),
0 2px 3px rgba($base-b, 0.18);
/*
* Mod scale
*/
$modularscale: (
base: 14px, ratio: 1.2,
480px: (base: 13px, ratio: 1.15),
768px: (base: 14px, ratio: 1.17),
1280px: (base: 14px, ratio: 1.2)
);

1048
_sass/vendor/iconfonts/ionicons@3.scss vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
// https://github.com/modularscale/modularscale-sass v3.0.3
// Ratios
$double-octave : 4 ;
$pi : 3.14159265359 ;
$major-twelfth : 3 ;
$major-eleventh : 2.666666667 ;
$major-tenth : 2.5 ;
$octave : 2 ;
$major-seventh : 1.875 ;
$minor-seventh : 1.777777778 ;
$major-sixth : 1.666666667 ;
$phi : 1.618034 ;
$golden : $phi ;
$minor-sixth : 1.6 ;
$fifth : 1.5 ;
$augmented-fourth : 1.41421 ;
$fourth : 1.333333333 ;
$major-third : 1.25 ;
$minor-third : 1.2 ;
$major-second : 1.125 ;
$minor-second : 1.066666667 ;
// Base config
$ms-base : 1em !default;
$ms-ratio : $fifth !default;
$modularscale : () !default;// Parse settings starting with defaults.
// Settings should cascade down like you would expect in CSS.
// More specific overrides previous settings.
@function ms-settings($b: false, $r: false, $t: false, $m: $modularscale) {
$base: $ms-base;
$ratio: $ms-ratio;
$thread: map-get($m, $t);
// Override with user settings
@if map-get($m, base) {
$base: map-get($m, base);
}
@if map-get($m, ratio) {
$ratio: map-get($m, ratio);
}
// Override with thread settings
@if $thread {
@if map-get($thread, base) {
$base: map-get($thread, base);
}
@if map-get($thread, ratio) {
$ratio: map-get($thread, ratio);
}
}
// Override with inline settings
@if $b {
$base: $b;
}
@if $r {
$ratio: $r;
}
@return $base $ratio;
}// Sass does not have native pow() support so this needs to be added.
// Compass and other libs implement this more extensively.
// In order to keep this simple, use those when they are avalible.
// Issue for pow() support in Sass: https://github.com/sass/sass/issues/684
@function ms-pow($b,$e) {
// Return 1 if exponent is 0
@if $e == 0 {
@return 1;
}
// If pow() exists (compass or mathsass) use that.
@if function-exists('pow') {
@return pow($b,$e);
}
// This does not support non-integer exponents,
// Check and return an error if a non-integer exponent is passed.
@if (floor($e) != $e) {
@error '
======================================================================
Non-integer values are not supported in modularscale by default.
Try using mathsass in your project to add non-integer scale support.
https://github.com/terkel/mathsass
======================================================================
'
}
// Seed the return.
$ms-return: $b;
// Multiply or divide by the specified number of times.
@if $e > 0 {
@for $i from 1 to $e {
$ms-return: $ms-return * $b;
}
}
@if $e < 0 {
@for $i from $e through 0 {
$ms-return: $ms-return / $b;
}
}
@return $ms-return;
}// Stripping units is not a best practice
// This function should not be used elsewhere
// It is used here because calc() doesn't do unit logic
// AND target ratios use units as a hack to get a number.
@function ms-unitless($val) {
@return ($val / ($val - $val + 1));
}// Basic list sorting
// Would like to replace with http://sassmeister.com/gist/30e4863bd03ce0e1617c
// Unfortunately libsass has a bug with passing arguments into the min() funciton.
@function ms-sort($l) {
// loop until the list is confirmed to be sorted
$sorted: false;
@while $sorted == false {
// Start with the assumption that the lists are sorted.
$sorted: true;
// Loop through the list, checking each value with the one next to it.
// Swap the values if they need to be swapped.
// Not super fast but simple and modular scale doesn't lean hard on sorting.
@for $i from 2 through length($l) {
$n1: nth($l,$i - 1);
$n2: nth($l,$i);
// If the first value is greater than the 2nd, swap them.
@if $n1 > $n2 {
$l: set-nth($l, $i, $n1);
$l: set-nth($l, $i - 1, $n2);
// The list isn't sorted and needs to be looped through again.
$sorted: false;
}
}
}
// Return the sorted list.
@return $l;
}// No reason to have decimal pixel values,
// normalize them to whole numbers.
@function ms-round-px($r) {
@if unit($r) == 'px' {
@return round($r);
}
@return $r;
}// Convert number string to number
@function ms-to-num($n) {
$l: str-length($n);
$r: 0;
$m: str-index($n,'.');
@if $m == null {
$m: $l + 1;
}
// Loop through digits and convert to numbers
@for $i from 1 through $l {
$v: str-slice($n,$i,$i);
@if $v == '1' { $v: 1; }
@elseif $v == '2' { $v: 2; }
@elseif $v == '3' { $v: 3; }
@elseif $v == '4' { $v: 4; }
@elseif $v == '5' { $v: 5; }
@elseif $v == '6' { $v: 6; }
@elseif $v == '7' { $v: 7; }
@elseif $v == '8' { $v: 8; }
@elseif $v == '9' { $v: 9; }
@elseif $v == '0' { $v: 0; }
@else { $v: null; }
@if $v != null {
$m: $m - 1;
$r: $r + ms-pow(10,$m - 1) * $v;
} @else {
$l: $l - 1;
}
}
@return $r;
}
// Find a ratio based on a target value
@function ms-target($t,$b) {
// Convert to string
$t: $t + '';
// Remove base units to calulate ratio
$b: ms-unitless(nth($b,1));
// Find where 'at' is in the string
$at: str-index($t,'at');
// Slice the value and target out
// and convert strings to numbers
$v: ms-to-num(str-slice($t,0,$at - 1));
$t: ms-to-num(str-slice($t,$at + 2));
// Solve the modular scale function for the ratio.
@return ms-pow(($v/$b),(1/$t));
}@function ms-function($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {
// Parse settings
$ms-settings: ms-settings($base,$ratio,$thread,$settings);
$base: nth($ms-settings, 1);
$ratio: nth($ms-settings, 2);
// Render target values from settings.
@if unit($ratio) != '' {
$ratio: ms-target($ratio,$base)
}
// Fast calc if not multi stranded
@if(length($base) == 1) {
@return ms-round-px(ms-pow($ratio, $v) * $base);
}
// Create new base array
$ms-bases: nth($base,1);
// Normalize base values
@for $i from 2 through length($base) {
// initial base value
$ms-base: nth($base,$i);
// If the base is bigger than the main base
@if($ms-base > nth($base,1)) {
// divide the value until it aligns with main base.
@while($ms-base > nth($base,1)) {
$ms-base: $ms-base / $ratio;
}
$ms-base: $ms-base * $ratio;
}
// If the base is smaller than the main base.
@elseif ($ms-base < nth($base,1)) {
// pump up the value until it aligns with main base.
@while $ms-base < nth($base,1) {
$ms-base: $ms-base * $ratio;
}
}
// Push into new array
$ms-bases: append($ms-bases,$ms-base);
}
// Sort array from smallest to largest.
$ms-bases: ms-sort($ms-bases);
// Find step to use in calculation
$vtep: floor($v / length($ms-bases));
// Find base to use in calculation
$ms-base: round(($v / length($ms-bases) - $vtep) * length($ms-bases)) + 1;
@return ms-round-px(ms-pow($ratio, $vtep) * nth($ms-bases,$ms-base));
}// Generate calc() function
// based on Mike Riethmuller's Precise control over responsive typography
// http://madebymike.com.au/writing/precise-control-responsive-typography/
@function ms-fluid($val1: 1em, $val2: 1em, $break1: 0, $break2: 0) {
$diff: ms-unitless($val2) - ms-unitless($val1);
// v1 + (v2 - v1) * ( (100vw - b1) / b2 - b1 )
@return calc( #{$val1} + #{ms-unitless($val2) - ms-unitless($val1)} * ( ( 100vw - #{$break1}) / #{ms-unitless($break2) - ms-unitless($break1)} ) );
}
// Main responsive mixin
@mixin ms-respond($prop, $val, $map: $modularscale) {
$base: $ms-base;
$ratio: $ms-ratio;
$first-write: true;
$last-break: null;
// loop through all settings with a breakpoint type value
@each $v, $s in $map {
@if type-of($v) == number {
@if unit($v) != '' {
// Write out the first value without a media query.
@if $first-write {
#{$prop}: ms-function($val, $thread: $v, $settings: $map);
// Not the first write anymore, reset to false to move on.
$first-write: false;
$last-break: $v;
}
// Write intermediate breakpoints.
@else {
@media (min-width: $last-break) and (max-width: $v) {
$val1: ms-function($val, $thread: $last-break, $settings: $map);
$val2: ms-function($val, $thread: $v, $settings: $map);
#{$prop}: ms-fluid($val1,$val2,$last-break,$v);
}
$last-break: $v;
}
}
}
}
// Write the last breakpoint.
@if $last-break {
@media (min-width: $last-break) {
#{$prop}: ms-function($val, $thread: $last-break, $settings: $map);
}
}
}// To attempt to avoid conflicts with other libraries
// all funcitons are namespaced with `ms-`.
// However, to increase usability, a shorthand function is included here.
@function ms($v: 0, $base: false, $ratio: false, $thread: false, $settings: $modularscale) {
@return ms-function($v, $base, $ratio, $thread, $settings);
}

78
assets/2017/script.js Normal file
View File

@ -0,0 +1,78 @@
$(function () {
const $root = $('[data-js-main-body]')
wrapify($root)
})
/*
* Isotope
*/
$(function () {
$('[data-js-h3-section-list]').each(function () {
var iso = new Isotope(this, {
itemSelector: '.h3-section',
transitionDuration: 0
})
})
})
/*
* Wraps h2 sections into h2-section.
* Wraps h3 sections into h3-section.
*/
function wrapify ($root) {
const $h2sections = groupify($root, {
tag: 'h2',
wrapper: '<div class="h2-section">',
body: '<div class="body h3-section-list" data-js-h3-section-list>'
})
$h2sections.each(function () {
const $body = $(this).children('[data-js-h3-section-list]')
groupify($body, {
tag: 'h3',
wrapper: '<div class="h3-section">',
body: '<div class="body">'
})
})
}
/*
* Groups stuff
*/
function groupify ($this, { tag, wrapper, body }) {
const $first = $this.children(':first-child')
let $result = $()
// Handle the markup before the first h2
if (!$first.is(tag)) {
const $sibs = $first.nextUntil(tag)
$result = $result.add(wrap($first, null, $first.add($sibs)))
}
$this.children(tag).each(function () {
const $sibs = $(this).nextUntil(tag)
const $heading = $(this)
$result = $result.add(wrap($heading, $heading, $sibs))
})
return $result
function wrap ($pivot, $first, $sibs) {
const $wrap = $(wrapper)
$wrap.addClass($pivot.attr('class'))
$pivot.before($wrap)
const $body = $(body)
$body.addClass($pivot.attr('class'))
$body.append($sibs)
if ($first) $wrap.append($first)
$wrap.append($body)
return $wrap
}
}

3
assets/2017/style.scss Normal file
View File

@ -0,0 +1,3 @@
---
---
@import '2017/style.scss';

194
elixir.md
View File

@ -1,29 +1,26 @@
--- ---
title: Elixir title: Elixir
category: Development category: Development
layout: 2017/sheet
--- ---
## Importing ## Reference
```elixir ### Primitives
require Redux # compiles a module
import Redux # compiles, and you can use without the `Redux.` prefix
use Redux # compiles, and runs Redux.__using__/1 | `nil` | Nil/null |
use Redux, async: true | `true` _/_ `false` | Boolean |
| `'hello'` | Char list |
| `<<2, 3>>` | Binary |
| `"hello"` | Binary string |
| `:hello` | Atom |
| `[a, b]` | List |
| `{a, b}` | Tuple |
| `%{a: "hello"}` | Map |
| `%MyStruct{a: "hello"}` | Struct |
| `fn -> ... end` | Function |
import Redux, only: [duplicate: 2] ### Type checks
import Redux, only: :functions
import Redux, only: :macros
alias Foo.Bar, as: Bar
alias Foo.Bar # same as above
alias Foo.{Bar, Baz}
import Foo.{Bar, Baz}
```
## Type checks
```elixir ```elixir
is_atom/1 is_atom/1
@ -33,12 +30,16 @@ is_function/1
is_function/2 is_function/2
is_integer/1 is_integer/1
is_float/1 is_float/1
```
```elixir
is_binary/1 is_binary/1
is_list/1 is_list/1
is_map/1 is_map/1
is_tuple/1 is_tuple/1
```
```elixir
is_nil/1 is_nil/1
is_number/1 is_number/1
is_pid/1 is_pid/1
@ -56,16 +57,40 @@ left <> right # concat string/binary
left =~ right # regexp left =~ right # regexp
``` ```
### Inspecting ### Importing
```elixir ```elixir
inspect(arg, opts \\ []) require Redux # compiles a module
import Redux # compiles, and you can use without the `Redux.` prefix
use Redux # compiles, and runs Redux.__using__/1
use Redux, async: true
import Redux, only: [duplicate: 2]
import Redux, only: :functions
import Redux, only: :macros
import Foo.{Bar, Baz}
```
### Aliases
```elixir
alias Foo.Bar, as: Bar
alias Foo.Bar # same as above
alias Foo.{Bar, Baz}
``` ```
## String ## String
### Functions
```elixir ```elixir
import String import String
```
```elixir
str = "hello" str = "hello"
str |> length() #=> 5 str |> length() #=> 5
str |> codepoints() #=> ["h", "e", "l", "l", "o"] str |> codepoints() #=> ["h", "e", "l", "l", "o"]
@ -75,19 +100,33 @@ str |> capitalize() #=> "Hello"
str |> match(regex) str |> match(regex)
``` ```
### Inspecting objects
```elixir
inspect(object, opts \\ [])
```
```elixir
value |> IO.inspect()
```
## Numbers ## Numbers
### Operations
```elixir ```elixir
abs(n) abs(n)
round(n)
rem(a, b) # remainder (modulo) rem(a, b) # remainder (modulo)
div(a, b) # integer division div(a, b) # integer division
round(n)
``` ```
### Float ### Float
```elixir ```elixir
import Float import Float
```
```elixir
n = 10.3 n = 10.3
n |> ceil() #=> 11.0 n |> ceil() #=> 11.0
n |> ceil(2) #=> 11.30 n |> ceil(2) #=> 11.30
@ -101,17 +140,20 @@ Float.parse("34") #=> { 34.0, "" }
```elixir ```elixir
import Integer import Integer
```
```elixir
n = 12 n = 12
digits(n) #=> [1, 2] n |> digits() #=> [1, 2]
to_char_list(n) #=> '12' n |> to_char_list() #=> '12'
to_string(n) n |> to_string() #=> "12"
is_even(n) n |> is_even()
is_odd(n) n |> is_odd()
# Different base: # Different base:
digits(n, 2) #=> [1, 1, 0, 0] n |> digits(2) #=> [1, 1, 0, 0]
to_char_list(n, 2) #=> '1100' n |> to_char_list(2) #=> '1100'
to_string(n, 2) n |> to_string(2) #=> "1100"
parse("12") #=> 12 parse("12") #=> 12
undigits([1, 2]) #=> 12 undigits([1, 2]) #=> 12
@ -129,42 +171,46 @@ Float.to_string(34.1, [decimals: 2, compact: true]) #=> "34.1"
## Map ## Map
### Defining
```elixir ```elixir
map = %{name: "hi"} # atom keys (:name) map = %{name: "hi"} # atom keys (:name)
map = %{"name" => "hi"} # string keys ("name") map = %{"name" => "hi"} # string keys ("name")
``` ```
### Updating ### Updating
```elixir ```elixir
import Map import Map
map = %{map | name: "yo"} # key must exist map = %{map | name: "yo"} # key must exist
put(map, :id, 2) #=> %{id: 2, name: "hi"} map |> put(:id, 2) #=> %{id: 2, name: "hi"}
put_new(map, :id, 2) # only if `id` doesn't exist (`||=`) map |> put_new(:id, 2) # only if `id` doesn't exist (`||=`)
put(map, :b, "Banana") map |> put(:b, "Banana")
merge(map, %{b: "Banana"}) map |> merge(%{b: "Banana"})
update(map, :a, &(&1 + 1)) map |> update(:a, &(&1 + 1))
update(map, :a, fun a -> a + 1 end) map |> update(:a, fun a -> a + 1 end)
{old, new} = get_and_update(map, :a, &(&1 || "default")) {old, new} = map |> get_and_update(:a, &(&1 || "default"))
``` ```
### Deleting ### Deleting
```elixir ```elixir
delete(map, :name) #=> "hi" map |> delete(:name) #=> "hi"
pop(map, :name) #=> %{id: 1} map |> pop(:name) #=> %{id: 1}
``` ```
### Reading ### Reading
```elixir ```elixir
get(map, :id) #=> 1 map |> get(:id) #=> 1
keys(map) #=> [:id, :name] map |> keys() #=> [:id, :name]
values(map) #=> [1, "hi"] map |> values() #=> [1, "hi"]
to_list(map) #=> [id: 1, name: "hi"] map |> to_list() #=> [id: 1, name: "hi"]
#=> [{:id, 1}, {:name, "hi"}] #=> [{:id, 1}, {:name, "hi"}]
``` ```
@ -186,8 +232,6 @@ Map.new([:a, :b], fn x -> {x, x} end) #=> %{a: :a, b: :b}
## List ## List
Also see [Enum](#enum).
```js ```js
import List import List
list = [ 1, 2, 3, 4 ] list = [ 1, 2, 3, 4 ]
@ -201,10 +245,12 @@ flatten(list)
flatten(list, tail) flatten(list, tail)
``` ```
Also see [Enum](#enum).
## Enum ## Enum
```elixir ```elixir
# consider streams instead
import Enum import Enum
# High-order # High-order
@ -223,14 +269,18 @@ any?(list) #=> true
concat(list, [:d]) #=> [:d] concat(list, [:d]) #=> [:d]
``` ```
Also, consider streams instead.
## Tuples ## Tuples
### Tuples
```elixir ```elixir
tuple = { :a, :b } tuple = { :a, :b }
elem(tuple, 1) # like tuple[1] tuple |> elem(1) # like tuple[1]
put_elem(tuple, index, value) tuple |> put_elem(index, value)
tuple_size(tuple) tuple |> tuple_size()
``` ```
### Keyword lists ### Keyword lists
@ -270,9 +320,17 @@ apply(fun, args)
apply(module, fun, args) apply(module, fun, args)
``` ```
## Syntax ### Function heads
### [Structs](http://elixir-lang.org/getting-started/structs.html) ```elixir
def join(a, b \\ nil)
def join(a, b) when is_nil(b) do: a
def join(a, b) do: a <> b
```
## Structs
### Structs
```elixir ```elixir
defmodule User do defmodule User do
@ -284,18 +342,12 @@ end
%User{}.struct #=> User %User{}.struct #=> User
``` ```
## Functions See: [Structs](http://elixir-lang.org/getting-started/structs.html)
### Function heads
```elixir
def join(a, b \\ nil)
def join(a, b) when is_nil(b) do: a
def join(a, b) do: a <> b
```
## Protocols ## Protocols
### Defining protocols
```elixir ```elixir
defprotocol Blank do defprotocol Blank do
@doc "Returns true if data is considered blank/empty" @doc "Returns true if data is considered blank/empty"
@ -330,6 +382,8 @@ end
## Comprehensions ## Comprehensions
### For
```elixir ```elixir
for n <- [1, 2, 3, 4], do: n * n for n <- [1, 2, 3, 4], do: n * n
for n <- 1..4, do: n * n for n <- 1..4, do: n * n
@ -356,7 +410,7 @@ for dir <- dirs,
end end
``` ```
## Modules ## Misc
### Metaprogramming ### Metaprogramming
@ -376,7 +430,7 @@ def on_def(_env, kind, name, args, guards, body)
def load_check def load_check
``` ```
## Regexp ### Regexp
```elixir ```elixir
exp = ~r/hello/ exp = ~r/hello/
@ -384,7 +438,7 @@ exp = ~r/hello/i
"hello world" =~ exp "hello world" =~ exp
``` ```
## [Sigils](http://elixir-lang.org/getting-started/sigils.html) ### Sigils
```elixir ```elixir
~r/regexp/ ~r/regexp/
@ -394,11 +448,10 @@ exp = ~r/hello/i
~c(char list) ~c(char list)
``` ```
Allowed chars: `/` `|` `"` `'` `(` `[` `{` `<` `"""` Allowed chars: `/` `|` `"` `'` `(` `[` `{` `<` `"""`.
See: [Sigils](http://elixir-lang.org/getting-started/sigils.html)
## [Typespecs](http://elixir-lang.org/getting-started/typespecs-and-behaviours.html) ### Type specs
Useful for [dialyzer](http://www.erlang.org/doc/man/dialyzer.html)
```elixir ```elixir
@spec round(number) :: integer @spec round(number) :: integer
@ -407,7 +460,10 @@ Useful for [dialyzer](http://www.erlang.org/doc/man/dialyzer.html)
@spec add(number, number) :: number_with_remark @spec add(number, number) :: number_with_remark
``` ```
## Behaviours Useful for [dialyzer](http://www.erlang.org/doc/man/dialyzer.html).
See: [Typespecs](http://elixir-lang.org/getting-started/typespecs-and-behaviours.html)
### Behaviours
```elixir ```elixir
defmodule Parser do defmodule Parser do
@ -425,9 +481,9 @@ defmodule JSONParser do
end end
``` ```
[Reference](http://elixir-lang.org/docs/stable/elixir/Module.html) See: [Module](http://elixir-lang.org/docs/stable/elixir/Module.html)
## References ## References
{: .-one-column}
- [Learn Elixir in Y minutes](https://learnxinyminutes.com/docs/elixir/) - [Learn Elixir in Y minutes](https://learnxinyminutes.com/docs/elixir/)

340
es6.md
View File

@ -1,16 +1,11 @@
--- ---
title: ES2015 title: ES2015
category: JavaScript category: JavaScript
layout: default-ad layout: 2017/sheet
ads: true
--- ---
## Stable in io.js ### Promises
New features you can use on [io.js](http://iojs.org/).
{:.brief-intro.center.top-space-0}
### [Promises](http://babeljs.io/docs/learn-es2015/#promises)
For asynchronous programming.
```js ```js
new Promise(fn) new Promise(fn)
@ -25,42 +20,57 @@ Promise.reject(/*...*/)
Promise.resolve(/*...*/) Promise.resolve(/*...*/)
``` ```
### [Block scoping](http://babeljs.io/docs/learn-es2015/#let-const) For asynchronous programming.
`let` is the new `var`. See: [Promises](http://babeljs.io/docs/learn-es2015/#promises)
### Block scoping
```js ```js
// Block scoping (let)
function fn () { function fn () {
let x = 0; let x = 0
if (true) { if (true) {
let x = 1; // only inside this `if` let x = 1 // only inside this `if`
} }
} }
``` ```
{: data-line="2,4"}
```js ```js
// Constants // Constants
const a = 1; const a = 1
``` ```
### [Backtick strings](http://babeljs.io/docs/learn-es2015/#template-strings) `let` is the new `var`.
Templates and multiline strings. See: [Let and const](http://babeljs.io/docs/learn-es2015/#let-const)
### Backtick strings
```js ```js
// Interpolation // Interpolation
var message = `Hello ${name}`; var message = `Hello ${name}`
``` ```
```js ```js
// Multiline // Multiline strings
var str = ` var str = `
hello hello
world world
`; `
``` ```
### Other improvements Templates and multiline strings.
New string [methods](http://babeljs.io/docs/learn-es2015/#math-number-string-object-apis), [binary and octal](http://babeljs.io/docs/learn-es2015/#binary-and-octal-literals) numbers. See: [Template strings](http://babeljs.io/docs/learn-es2015/#template-strings)
### Binary and octal literals
```js
let bin = 0b1010010
let oct = 0755
```
See: [Binary and octal literals](http://babeljs.io/docs/learn-es2015/#binary-and-octal-literals)
### New methods
```js ```js
// New string methods // New string methods
@ -69,134 +79,43 @@ New string [methods](http://babeljs.io/docs/learn-es2015/#math-number-string-obj
"\u1E9B\u0323".normalize("NFC") "\u1E9B\u0323".normalize("NFC")
``` ```
```js See: [New methods](http://babeljs.io/docs/learn-es2015/#math-number-string-object-apis)
// Binary/octal literals
var bin = 0b1010010;
var oct = 0755;
```
### [Object literal enhancements](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals) ### Classes
Adds support for getters, setters, methods, shorthand.
```js
// Short object syntax
// aka: `exports = { hello:hello, bye:bye }`
module.exports = { hello, bye };
```
```js
App = {
// shorthand for `handler: handler`
handler,
// methods
start() {
this.go();
},
// getter/setter
get closed() {
return this.status === 'closed';
},
// custom prototypes
__proto__: protoObj,
// computed property names
[ "prop_"+n ]: 42
};
```
### [Generators](http://babeljs.io/docs/learn-es2015/#generators)
It's complicated.
```js
function* idMaker() {
var id = 0;
while (true) { yield id++; }
}
var gen = idMaker();
gen.next().value // 0
gen.next().value // 1
gen.next().value // 2
```
### [Classes](http://babeljs.io/docs/learn-es2015/#classes)
Syntactic sugar for prototypes.
```js ```js
class Circle extends Shape { class Circle extends Shape {
// ctor // ctor
constructor(radius) { constructor (radius) {
this.radius = radius; this.radius = radius
} }
// methods // methods
getArea() { getArea () {
return Math.PI * 2 * this.radius; return Math.PI * 2 * this.radius
} }
// calling super methods // calling super methods
expand(n) { expand (n) {
return super.expand(n) * Math.PI; return super.expand(n) * Math.PI
} }
// static methods // static methods
static createFromDiameter(diameter) { static createFromDiameter(diameter) {
return new Circle(diameter / 2); return new Circle(diameter / 2)
} }
} }
``` ```
<br> Syntactic sugar for prototypes.
See: [Classes](http://babeljs.io/docs/learn-es2015/#classes)
## Stable in Babel ### Destructuring
Available via the [Babel] transpiler.
{:.brief-intro.center.top-space-0}
### [Module imports](http://babeljs.io/docs/learn-es2015/#modules)
`import` is the new `require()`.
```js
// aka: require('...')
import 'helpers';
// aka: Express = require('...')
import Express from 'express';
// aka: indent = require('...').indent
import { indent } from 'helpers';
// aka: indent = require('...').indentSpaces
import { indentSpaces as indent } from 'helpers';
```
### [Module exports](http://babeljs.io/docs/learn-es2015/#modules)
`export` is the new `module.exports =`.
```js
// aka: module.exports = ...
export default function () {
// ...
};
// aka: exports.mymethod = ...
export function mymethod () {
};
// aka: exports.pi = ...
export var pi = 3.14159;
```
### [Destructuring](http://babeljs.io/docs/learn-es2015/#destructuring)
Supports for matching arrays and objects.
```js ```js
// Destructuring assignment // Destructuring assignment
var [first, last] = ["Nikola", "Tesla"]; var [first, last] = ['Nikola', 'Tesla']
let {title, author} = { title: "The Silkworm", author: "R. Galbraith" }; let {title, author} = { title: 'The Silkworm', author: 'R. Galbraith' }
``` ```
```js ```js
@ -212,16 +131,21 @@ function greet({ name, greeting }) {
// ... // ...
} }
greet({ name: "Larry", greeting: "Ahoy" }); greet({ name: 'Larry', greeting: 'Ahoy' })
``` ```
### [Function arguments](http://babeljs.io/docs/learn-es2015/#default-rest-spread) Supports for matching arrays and objects.
Default, rest, spread. (iojs: `--harmony-rest-parameters`) See: [Destructuring](http://babeljs.io/docs/learn-es2015/#destructuring)
Functions
---------
### Function arguments
```js ```js
// Default arguments // Default arguments
function greet(name = "Jerry") { function greet (name = "Jerry") {
return `Hello ${name}`; return `Hello ${name}`
} }
``` ```
@ -229,39 +153,174 @@ function greet(name = "Jerry") {
// Rest arguments // Rest arguments
function fn(x, ...y) { function fn(x, ...y) {
// y is an Array // y is an Array
return x * y.length; return x * y.length
} }
``` ```
```js ```js
// Spread // Spread
fn(...[1,2,3]) // same as fn(1,2,3) fn(...[1, 2, 3]) // same as fn(1, 2, 3)
``` ```
### [Fat arrows](http://babeljs.io/docs/learn-es2015/#arrows) Default, rest, spread.
Like functions but with `this` preserved. See: [Function arguments](http://babeljs.io/docs/learn-es2015/#default-rest-spread)
### Fat arrows
```js ```js
// Fat arrows // Fat arrows
setTimeout(() => { setTimeout(() => {
... ...
}); })
``` ```
```js ```js
// With arguments // With arguments
readFile('text.txt', (err, data) => { readFile('text.txt', (err, data) => {
... ...
}); })
``` ```
```js ```js
// Short syntax (no `return` without `{}`) // Short syntax (no `return` without `{}`)
numbers.map(n => n * 2) numbers.map(n => n * 2)
// Same as: numbers.map(function (n) { return n * 2 })
``` ```
### [For..of iteration](http://babeljs.io/docs/learn-es2015/#iterators-for-of) Like functions but with `this` preserved.
For iterating through generators and arrays. See: [Fat arrows](http://babeljs.io/docs/learn-es2015/#arrows)
Objects
-------
### Shorthand syntax
```js
module.exports = { hello, bye }
// Same as: module.exports = { hello: hello, bye: bye }
```
See: [Object literal enhancements](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals)
### Methods
```js
const App = {
start () {
console.log('running')
}
}
// Same as: App = { start: function () {···} }
```
{: data-line="2"}
See: [Object literal enhancements](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals)
### Getters and setters
```js
const App = {
get closed () {
return this.status === 'closed'
},
set closed (value) {
this.status === value ? 'closed' : 'open'
}
}
```
{: data-line="2,5"}
See: [Object literal enhancements](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals)
### Computed property names
```js
let event = 'click'
let handlers = {
['on' + event]: true
}
// Same as: handlers = { 'onclick': true }
```
{: data-line="3"}
See: [Object literal enhancements](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals)
Modules
-------
### Imports
```js
import 'helpers'
// aka: require('···')
```
```js
import Express from 'express'
// aka: Express = require('···').default || require('···')
```
```js
import { indent } from 'helpers'
// aka: indent = require('···').indent
```
```js
import * as Helpers from 'helpers'
// aka: Helpers = require('···')
```
```js
import { indentSpaces as indent } from 'helpers'
// aka: indent = require('···').indentSpaces
```
`import` is the new `require()`.
See: [Module imports](http://babeljs.io/docs/learn-es2015/#modules)
### Exports
```js
export default function () { ··· }
// aka: module.exports.default = ···
```
```js
export function mymethod () { ··· }
// aka: module.exports.mymethod = ···
```
```js
export const pi = 3.14159
// aka: module.exports.pi = ···
```
`export` is the new `module.exports`.
See: [Module exports](http://babeljs.io/docs/learn-es2015/#modules)
Generators
----------
### Generators
```js
function* idMaker () {
var id = 0
while (true) { yield id++ }
}
```
```js
var gen = idMaker()
gen.next().value // 0
gen.next().value // 1
gen.next().value // 2
```
It's complicated.
See: [Generators](http://babeljs.io/docs/learn-es2015/#generators)
### For..of iteration
```js ```js
for (let i of iterable) { for (let i of iterable) {
@ -269,4 +328,5 @@ for (let i of iterable) {
} }
``` ```
[Babel]: http://babeljs.io For iterating through generators and arrays.
See: [For..of iteration](http://babeljs.io/docs/learn-es2015/#iterators-for-of)

View File

@ -1,8 +1,11 @@
--- ---
title: ExUnit title: ExUnit
category: Elixir category: Elixir
layout: 2017/sheet
--- ---
### Test cases
```elixir ```elixir
defmodule MyTest do defmodule MyTest do
use ExUnit.Case use ExUnit.Case
@ -43,7 +46,7 @@ defmodule AssertionTest do
end end
``` ```
### [Assertions](http://devdocs.io/elixir/ex_unit/exunit.assertions) ### Assertions
```elixir ```elixir
assert x == y assert x == y
@ -57,8 +60,11 @@ assert_raise ArithmeticError, "message", fn -> ...
assert_raise ArithmeticError, ~r/message/, fn -> ... assert_raise ArithmeticError, ~r/message/, fn -> ...
flunk "This should've been an error" flunk "This should've been an error"
```
See: [Assertions](http://devdocs.io/elixir/ex_unit/exunit.assertions)
## Also see ## Also see
{: .-one-column}
- <http://devdocs.io/elixir/ex_unit/exunit#configure/1> - <http://devdocs.io/elixir/ex_unit/exunit#configure/1>

503
jekyll.md
View File

@ -1,12 +1,55 @@
--- ---
title: Jekyll title: Jekyll
jekyll_escape: true jekyll_escape: true
layout: 2017/sheet
--- ---
{% raw %} {% raw %}
### Installation ### Installation
$ gem install jekyll ```bash
# Install the gems
gem install jekyll bundler
```
```bash
# Create a new site at `./myblog`
jekyll new myblog
```
```bash
cd myblog
bundle exec jekyll serve
```
See: [Jekyll quickstart](http://jekyllrb.com/docs/quickstart/)
### Installation (GitHub pages version)
```bash
# Requires bundler
gem install bundler
```
```bash
# Build the Gemfile
echo "source 'https://rubygems.org'" > Gemfile
echo "gem 'github-pages', group: :jekyll_plugins" >> Gemfile
```
```bash
# Install gems
bundle
```
```bash
# Start server
bundle exec jekyll serve
```
This is the recommended setup, especially if you're using GitHub pages.
See: [github/pages-gem](https://github.com/github/pages-gem)
### Directories ### Directories
@ -33,13 +76,18 @@ jekyll_escape: true
└── _site/ └── _site/
└── ... └── ...
## [Front-matter](http://jekyllrb.com/docs/frontmatter/) ## Front-matter
{: .-three-column}
### Basic frontmatter
--- ---
layout: post layout: post
title: Hello title: Hello
--- ---
See: [Front-matter](http://jekyllrb.com/docs/frontmatter/)
### Other frontmatter stuff ### Other frontmatter stuff
permalink: '/hello' permalink: '/hello'
@ -48,86 +96,29 @@ jekyll_escape: true
categories: ['html', 'css'] categories: ['html', 'css']
tags: ['html', 'css'] tags: ['html', 'css']
## [Configuration](http://jekyllrb.com/docs/configuration/) ### Configuration
source: . source: .
destination: _site destination: _site
exclude: [dir, file, ...] exclude: [dir, file, ...]
include: ['.htaccess'] include: ['.htaccess']
## [Variables](http://jekyllrb.com/docs/variables/) See: [Configuration](http://jekyllrb.com/docs/configuration/)
{{ site }} - from config.yml
{{ page }} - from frontmatter, and page-specific info
{{ content }} - html content (use in layouts)
{{ paginator }} - ...
### Site
{{ site.time }} - current time
{{ site.pages }} - list of pages
{{ site.posts }} - list of posts
{{ site.related_posts }} - list
{{ site.categories.CATEGORY }} - list
{{ site.tags.TAG }} - list
{{ site.static_files }}
### Page
{{ page.content }} - un-rendered content
{{ page.title }}
{{ page.excerpt }} - un-rendered excerpt
{{ page.url }}
{{ page.date }}
{{ page.id }} - unique id for RSS feeds
{{ page.categories }}
{{ page.tags }}
{{ page.path }}
{{ post.excerpt | remove: '<p>' | remove: '</p>' }}
{{ post.excerpt | strip_html }}
<!-- blog pagination: -->
{{ page.next }}
{{ page.previous }}
### [Paginator](http://jekyllrb.com/docs/pagination/)
{{ paginator.page }} - page number
{{ paginator.total_posts }}
{{ paginator.total_pages }}
{{ paginator.per_page }}
{% for post in paginator.posts %} ... {% endfor %}
{% if paginator.previous_page %}
<a href="{{ paginator.previous_page_path }}">Previous</a>
{% else %}
{% endif %}
{{ paginator.next_page }} - page number
{{ paginator.next_page_path }}
...
{% if paginator.total_pages > 1 %}
{% endif %}
Add this to `_config.yml`:
paginate: 5
paginate_path: "blog/:num"
### Code
{% highlight ruby linenos %}
def show
...
end
{% endhighlight %}
Markup Markup
------ ------
### Page variables
```html
<title>{{ page.title }}</title>
```
```html
<!-- Filters -->
<p>{{ page.description | truncate_words: 20 }}
```
### Loops ### Loops
{% for post in site.posts %} {% for post in site.posts %}
@ -150,37 +141,174 @@ Markup
### Includes (partials) ### Includes (partials)
{% include header.html %} ```
{% include header.html %}
```
## [Blogging](http://jekyllrb.com/docs/posts/) ```html
<!-- Including local vars -->
{% include header.html page=page %}
```
### Comments
```html
{% comment %}
{% endcomment %}
```
## Expression
### Top-level variables
{{ site }} - from config.yml
{{ page }} - from frontmatter, and page-specific info
{{ content }} - html content (use in layouts)
{{ paginator }} - ...
See: [Variables](http://jekyllrb.com/docs/variables/)
### Site
{{ site.time }} - current time
{{ site.pages }} - list of pages
{{ site.posts }} - list of posts
{{ site.related_posts }} - list
{{ site.categories.CATEGORY }} - list
{{ site.tags.TAG }} - list
{{ site.static_files }}
### Page
```html
{{ page.content }} - un-rendered content
{{ page.title }}
{{ page.excerpt }} - un-rendered excerpt
{{ page.url }}
{{ page.date }}
{{ page.id }} - unique id for RSS feeds
{{ page.categories }}
{{ page.tags }}
{{ page.path }}
{{ post.excerpt | remove: '<p>' | remove: '</p>' }}
{{ post.excerpt | strip_html }}
```
```html
<!-- blog pagination: -->
{{ page.next }}
{{ page.previous }}
```
## Paginator
### Paginator setup
Add this to `_config.yml`:
{: .-setup}
```yml
paginate: 5
paginate_path: "blog/:num"
```
See: [Paginator](http://jekyllrb.com/docs/pagination/)
### Numbers
```
{{ paginator.page }} - page number
{{ paginator.total_posts }}
{{ paginator.total_pages }}
{{ paginator.per_page }}
```
### Iterating through posts
```
{% for post in paginator.posts %} ... {% endfor %}
```
### Previous button
```
{% if paginator.total_pages > 1 %}
{% if paginator.previous_page %}
<a href="{{ paginator.previous_page_path }}">Previous</a>
{% else %}
{% endif %}
{% endif %}
```
```
{{ paginator.next_page }} - page number
{{ paginator.next_page_path }}
```
## Blogging
### Paths
_posts/YEAR-MONTH-DAY-title.md _posts/YEAR-MONTH-DAY-title.md
### [Image paths](http://jekyllrb.com/docs/posts/#including-images-and-resources) See: [Blogging](http://jekyllrb.com/docs/posts/)
### Image paths
![My helpful screenshot]({{ site.url }}/assets/screenshot.jpg) ![My helpful screenshot]({{ site.url }}/assets/screenshot.jpg)
### [Drafts](http://jekyllrb.com/docs/drafts/) See: [Image paths](http://jekyllrb.com/docs/posts/#including-images-and-resources)
### Drafts
vi _drafts/a-draft-post.md vi _drafts/a-draft-post.md
jekyll build --drafts jekyll build --drafts
### [Excerpts](http://jekyllrb.com/docs/posts/#post-excerpts) Posts in `_drafts` only show up in development, but not production.
See: [Drafts](http://jekyllrb.com/docs/drafts/)
{{ post.excerpt | remove: '<p>' | remove: '</p>' }} ### Defining excerpts
{{ post.excerpt | strip_html }}
```
---
title: My blog post
excerpt: This post is about cats
---
Hello, let's talk about cats. (···)
```
Put a key `excerpt` in the frontmatter.
See: [Excerpts](http://jekyllrb.com/docs/posts/#post-excerpts)
### Displaying excerpts
```html
{{ post.excerpt }}
```
```html
{{ post.excerpt | remove: '<p>' | remove: '</p>' }}
{{ post.excerpt | strip_html }}
```
### Excerpt separator ### Excerpt separator
--- ```html
excerpt_separator: <!--more--> ---
--- excerpt_separator: <!--more-->
---
Excerpt Excerpt here
<!--more--> <!--more-->
Out-of-excerpt More post body here
```
### [Permalinks](http://jekyllrb.com/docs/permalinks/) Alternatively, you can put excerpts inline in your post by defining `excerpt_separator`.
### Permalinks
# _config.yml # _config.yml
permalink: date # /:categories/:year/:month/:day/:title.html permalink: date # /:categories/:year/:month/:day/:title.html
@ -188,21 +316,35 @@ Markup
permalink: none # /:categories/:title.html permalink: none # /:categories/:title.html
permalink: "/:title" permalink: "/:title"
## [Data](http://jekyllrb.com/docs/datafiles/) See: [Permalinks](http://jekyllrb.com/docs/permalinks/)
_data/members.yml ## More features
{% for member in site.data.members %} ### Data
## [Collections](http://jekyllrb.com/docs/collections/) ```
_data/members.yml
```
{: .-setup}
```yaml ```
{% for member in site.data.members %}
...
{% endfor %}
```
See: [Data](http://jekyllrb.com/docs/datafiles/)
### Collections
```yml
# _config.yml # _config.yml
collections: collections:
- authors - authors
``` ```
{: .-setup}
```yaml ```yml
# _/authors/a-n-roquelaire.md # _/authors/a-n-roquelaire.md
--- ---
name: A. N. Roquelaire name: A. N. Roquelaire
@ -214,79 +356,115 @@ real_name: Anne Rice
{% for author in site.authors %} {% for author in site.authors %}
``` ```
Helpers and Filters See: [Collections](http://jekyllrb.com/docs/collections/)
Helpers and filters
------------------- -------------------
### Dates ### Dates
{{ site.time | date_to_xmlschema }} #=> 2008-11-07T13:07:54-08:00 ```
{{ site.time | date_to_rfc822 }} #=> Mon, 07 Nov 2008 13:07:54 -0800 {{ site.time | date_to_xmlschema }} #=> 2008-11-07T13:07:54-08:00
{{ site.time | date_to_string }} #=> 07 Nov 2008 {{ site.time | date_to_rfc822 }} #=> Mon, 07 Nov 2008 13:07:54 -0800
{{ site.time | date_to_long_string }} #=> 07 November 2008 {{ site.time | date_to_string }} #=> 07 Nov 2008
| date: "%Y %m %d" {{ site.time | date_to_long_string }} #=> 07 November 2008
{{ site.time | date: "%Y %m %d" }}
```
### Preprocessors ### Preprocessors
| textilize ```
| markdownify | textilize
| jsonify | markdownify
| sassify | jsonify
| scssify | sassify
| scssify
```
### Array ### Array filters
site.posts | where:"year","2014" ```
site.posts | group_by:"genre" #=> { name, items } site.posts | where:"year","2014"
site.posts | sort site.posts | group_by:"genre" #=> { name, items }
site.posts | sort
```
| first ```
| last | first
| join: "," | last
| array_to_sentence_string #=> CSS, JavaScript and HTML | join: ","
| array_to_sentence_string #=> CSS, JavaScript and HTML
```
| map: "post" # works like 'pluck' ```
| size | map: "post" # works like 'pluck'
| size
```
### [String filters](http://docs.shopify.com/themes/liquid-documentation/filters) ### String filters
| default: "xxx" ```rb
| default: "xxx"
```
| upcase ```rb
| downcase | upcase
| downcase
```
| remove: "<p>" ```rb
| replace: "super", "mega" | remove: "<p>"
| remove_first: "<p>" | replace: "super", "mega"
| replace_first: "super", "mega" | remove_first: "<p>"
| replace_first: "super", "mega"
```
| truncate: 5 ```rb
| truncatewords: 20 | truncate: 5
| truncatewords: 20
```
| prepend: "Mr. " ```rb
| append: " Sr." | prepend: "Mr. "
| append: " Sr."
```
| camelize ```rb
| capitalize | camelize
| pluralize | capitalize
| strip_html | pluralize
| strip_newlines | strip_html
| newline_to_br | strip_newlines
| newline_to_br
```
| split: ',' ```rb
| split: ','
```
| escape ```rb
| escape_once | escape
| escape_once
```
| slice: -3, 3 ```rb
| slice: -3, 3
```
### String filters, Jekyll-only See: [String filters](http://docs.shopify.com/themes/liquid-documentation/filters)
| number_of_words ### String filters (Jekyll-only)
| slugify
| xml_escape #=> CDATA ```
| cgi_escape #=> foo%2Cbar | number_of_words
| uri_escape #=> foo,%20bar | slugify
```
```rb
| xml_escape #=> CDATA
| cgi_escape #=> foo%2Cbar
| uri_escape #=> foo,%20bar
```
### Numbers ### Numbers
@ -295,33 +473,44 @@ Helpers and Filters
| time: 4 | time: 4
| divided_by: 3 | divided_by: 3
| modulo: 2 | modulo: 2
Comments
--------
{% comment %} ### Code highlighter
{% endcomment %}
```html
{% highlight ruby linenos %}
def show
...
end
{% endhighlight %}
```
Integration Integration
----------- -----------
### Bundler ### Bundler
# _plugins/bundler.rb In `_plugins/bundler.rb`:
require "bunder/setup"
Bundler.require :default ```rb
require "bunder/setup"
Bundler.require :default
```
### Compass ### Compass
* [Compass](https://gist.github.com/parkr/2874934) * [Compass](https://gist.github.com/parkr/2874934)
* [Asset pipeline](https://github.com/matthodan/jekyll-asset-pipeline) * [Asset pipeline](https://github.com/matthodan/jekyll-asset-pipeline)
### References Also see
--------
{: .-one-column}
* [Jekyll docs](http://jekyllrb.com/docs/home/) _jekyllrb.com_
* [Jekyll: templates](http://jekyllrb.com/docs/templates/) _jekyllrb.com_
* [Liquid: output](http://docs.shopify.com/themes/liquid-basics/output) _shopify.com_
* [Liquid: logic](http://docs.shopify.com/themes/liquid-basics/logic) _shopify.com_
* [Liquid: filters](http://docs.shopify.com/themes/liquid-documentation/filters) _shopify.com_
* [Liquid for designers](https://github.com/Shopify/liquid/wiki/Liquid-for-Designers) _github.com/Shopify_
{: .-also-see}
* http://jekyllrb.com/docs/home/
* http://jekyllrb.com/docs/templates/
* http://docs.shopify.com/themes/liquid-basics/output
* http://docs.shopify.com/themes/liquid-basics/logic
* https://github.com/Shopify/liquid/wiki/Liquid-for-Designers
* http://docs.shopify.com/themes/liquid-documentation/filters
{% endraw %} {% endraw %}

View File

@ -1,8 +1,22 @@
--- ---
title: Stream title: Node.js streams
category: Node.js category: Node.js
layout: 2017/sheet
--- ---
### Types
| Stream | Description |
| --- | --- |
| `Readable` | Data emitter |
| `Writable` | Data receiver |
| `Transform` | Emitter and receiver |
| `Duplex` | Emitter and receiver (independent) |
See: [Stream](https://nodejs.org/api/stream.html#stream_stream) _(nodejs.org)_
### Streams
```js ```js
const Readable = require('stream').Readable const Readable = require('stream').Readable
const Writable = require('stream').Writable const Writable = require('stream').Writable
@ -12,36 +26,71 @@ const Transform = require('stream').Transform
### Piping ### Piping
```js ```js
clock() // Readable stream clock() // Readable stream
.pipe(xformer()) // Transform stream .pipe(xformer()) // Transform stream
.pipe(renderer()) // Writable stream .pipe(renderer()) // Writable stream
``` ```
### Readable streams ### Methods
Readable streams are generators of data. Write data using `stream.push()`. ```js
stream.push(/*...*/) // Emit a chunk
stream.emit('error', error) // Raise an error
stream.push(null) // Close a stream
```
### Events
```js
const st = source()
st.on('data', (data) => { console.log('<-', data) })
st.on('error', (err) => { console.log('!', err.message) })
st.on('close', () => { console.log('** bye') })
st.on('finish', () => { console.log('** bye') })
```
Assuming `source()` is a readable stream.
### Flowing mode
```js
// Toggle flowing mode
st.resume()
st.pause()
```
```js
// Automatically turns on flowing mode
st.on('data', /*...*/)
```
Stream types
------------
{: .-three-column}
### Readable
```js ```js
function clock () { function clock () {
const stream = new Readable({ const stream = new Readable({
objectMode: true, objectMode: true,
read: () => {} // implement this if you need on-demand reading read() {}
}) })
setInterval(() => { setInterval(() => {
stream.push({ time: new Date() }) stream.push({ time: new Date() })
if (error) return stream.emit('error', error)
if (eof) return stream.push(null)
}, 1000) }, 1000)
return stream return stream
} }
// Implement read() if you
// need on-demand reading.
``` ```
### Transform streams Readable streams are generators of data. Write data using `stream.push()`.
Pass the updated chunk to `done(null, chunk)`. ### Transform
```js ```js
function xformer () { function xformer () {
@ -50,13 +99,15 @@ function xformer () {
return new Transform({ return new Transform({
objectMode: true, objectMode: true,
transform: (data, _, done) => { transform: (data, _, done) => {
done(null, { time: data.time, index: count++ }) done(null, { ...data, index: count++ })
} }
}) })
} }
``` ```
### Writable streams Pass the updated chunk to `done(null, chunk)`.
### Writable
```js ```js
function renderer () { function renderer () {
@ -70,14 +121,16 @@ function renderer () {
} }
``` ```
### Reading ### All together now
```js ```js
const st = source() clock() // Readable stream
st.on('data', (data) => { console.log('<-', data) }) .pipe(xformer()) // Transform stream
st.on('close', () => { console.log('** bye') }) .pipe(renderer()) // Writable stream
``` ```
## Also see ## Also see
{: .-one-column}
- <https://nodejs.org/api/stream.html>
- <https://github.com/substack/stream-handbook> - <https://github.com/substack/stream-handbook>

76
rdoc.md
View File

@ -1,6 +1,7 @@
--- ---
title: Rdoc title: Rdoc
category: Markup category: Markup
layout: 2017/sheet
--- ---
### Basic RDoc format ### Basic RDoc format
@ -17,31 +18,45 @@ category: Markup
# @see http://url.com # @see http://url.com
# #
# @return [true] if so # @return [true] if so
#
# == Definition lists
#
# list:: hi.
# +foo+:: parameterized
#
# == Definition lists
# [foo] also
# [bar] like this
### Inline ### Inline
*bold* ```
_emphasized_ *bold*
+code+ _emphasized_
+code+
```
http://www.link.com ```
See Models::User@Examples http://www.link.com
{Google}[http://google.com] See Models::User@Examples
{Google}[http://google.com]
```
### Skip ### Skip
def input # :nodoc: ```rb
def input # :nodoc:
```
module MyModule # :nodoc: all ```rb
module MyModule # :nodoc: all
```
### Definition lists
```
# == Definition lists
#
# list:: hi.
# +foo+:: parameterized
```
```
# == Definition lists
# [foo] also
# [bar] like this
```
### Return types ### Return types
@ -65,17 +80,26 @@ category: Markup
### Sections ### Sections
# :section: Expiry methods ```rb
# methods relating to expiring # :section: Expiry methods
# methods relating to expiring
def expire! def expire!
def expired? def expired?
... ...
```
### Using tomdoc ### Using tomdoc
# :markup: TomDoc ```
# at the beginning ofthe file # :markup: TomDoc
```
http://rdoc.rubyforge.org/RDoc/Markup.html Plase this at the beginning of the file.
http://www.rubydoc.info/gems/yard/file/docs/GettingStarted.md
## Also see
{: .-one-column}
* <http://rdoc.rubyforge.org/RDoc/Markup.html>
* <http://www.rubydoc.info/gems/yard/file/docs/GettingStarted.md>
{: .-also-see}

719
react.md
View File

@ -1,416 +1,491 @@
--- ---
title: React.js title: React.js
category: React category: React
layout: default-ad layout: 2017/sheet
ads: true
--- ---
{%raw%} {%raw%}
Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output)) Components
{:.brief-intro.center} ----------
{: .-three-column}
```js ### Components
var Component = React.createClass({ {: .-prime}
render: function () {
return <div>Hello {this.props.name}</div>; ```jsx
import React from 'react'
import ReactDOM from 'react-dom'
```
{: .-setup}
```jsx
class Hello extends React.Component {
render () {
return <div className='message-box'>
Hello {this.props.name}
</div>
} }
});
```
```js
ReactDOM.render(<Component name="John" />, document.body);
```
{:.light}
## Nesting
Nest components to separate concerns. See [multiple components](http://facebook.github.io/react/docs/multiple-components.html).
{:.center}
```js
var UserAvatar = React.createClass({...});
var UserProfile = React.createClass({...});
```
{:.light}
```js
var Info = React.createClass({
render() {
return <div>
<UserAvatar src={this.props.avatar} />
<UserProfile username={this.props.username} />
</div>;
}
});
```
## States & Properties
Use [props](https://facebook.github.io/react/docs/tutorial.html#using-props) (`this.props`) to access parameters passed from the parent.
Use [states](https://facebook.github.io/react/docs/tutorial.html#reactive-state) (`this.state`) to manage dynamic data.
{:.center}
```html
<MyComponent fullscreen={true} />
```
{:.light}
```js
// props
this.props.fullscreen //=> true
// state
this.setState({ username: 'rstacruz' });
this.replaceState({ ... });
this.state.username //=> 'rstacruz'
```
```js
render: function () {
return <div className={this.props.fullscreen ? 'full' : ''}>
Welcome, {this.state.username}
</div>;
} }
``` ```
### Setting defaults ```jsx
Pre-populates `this.state.comments` and `this.props.name`. const el = document.body
ReactDOM.render(<Hello name='John' />, el)
```
```js Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output))
React.createClass({
getInitialState: function () {
return { comments: [] };
},
getDefaultProps: function () { ### Properties
return { name: "Hello" };
```html
<Video fullscreen={true} />
```
{: .-setup}
```jsx
render () {
this.props.fullscreen
···
}
```
{: data-line="2"}
Use `this.props` to access properties passed to the component.
See: [Properties](https://facebook.github.io/react/docs/tutorial.html#using-props)
### States
```jsx
this.setState({ username: 'rstacruz' })
```
```jsx
render () {
this.state.username
···
}
```
Use states (`this.state`) to manage dynamic data.
See: [States](https://facebook.github.io/react/docs/tutorial.html#reactive-state)
### Function components
```jsx
function MyComponent ({ name }) {
return <div className='message-box'>
Hello {name}
</div>
}
```
Functional components have no state. Also, their `props` are passed as the first parameter to a function.
See: [Function and Class Components](https://facebook.github.io/react/docs/components-and-props.html#functional-and-class-components)
### Nesting
```jsx
class Info extends React.Component {
render () {
const { avatar, username } = this.props
return <div>
<UserAvatar src={avatar} />
<UserProfile username={username} />
</div>
} }
); }
```
{: data-line="6,7"}
Nest components to separate concerns. See: [Composing Components](https://facebook.github.io/react/docs/components-and-props.html#composing-components)
### Setting default props
```jsx
Hello.defaultProps = {
color: 'blue'
}
``` ```
## Component API See: [defaultProps](https://facebook.github.io/react/docs/react-component.html#defaultprops)
These are methods available for `Component` instances. See [Component API](http://facebook.github.io/react/docs/component-api.html). ### Setting default state
{:.center}
```js ```jsx
ReactDOM.findDOMNode(c) // 0.14+ class Hello extends React.Component {
React.findDOMNode(c) // 0.13 constructor (props) {
c.getDOMNode() // 0.12 below super(props)
this.state = { visible: true }
}
}
``` ```
{:.light} {: data-line="4"}
```js Set the default state in the `constructor()`.
c.forceUpdate()
c.isMounted()
c.state ### Children
c.props
c.setState({ ... }) ```jsx
c.replaceState({ ... }) class AlertBox extends React.Component {
render () {
return <div className='alert-box'>
{this.props.children}
</div>
}
}
```
{: data-line="4"}
c.setProps({ ... }) // for deprecation ```jsx
c.replaceProps({ ... }) // for deprecation <AlertBox>
<h1>You have pending notifications</h1>
c.refs </AlertBox>
``` ```
### Component specs Children are passed as the `children` property.
Methods and properties you can override. See [component specs](http://facebook.github.io/react/docs/component-specs.html).
| Method | What | ### Component API
| ---- | ---- |
| [`render()`](http://facebook.github.io/react/docs/component-specs.html#render) | |
| ---- | ---- |
| [`getInitialState()`](http://facebook.github.io/react/docs/component-specs.html#getinitialstate) | |
| [`getDefaultProps()`](http://facebook.github.io/react/docs/component-specs.html#getdefaultprops) | |
| ---- | ---- |
| [`mixins: [ ... ]`](http://facebook.github.io/react/docs/component-specs.html#mixins) | Mixins ... [more](#mixins) |
| [`propTypes: { ... }`](http://facebook.github.io/react/docs/component-specs.html#proptypes) | Validation ... [more](#property-validation) |
| [`statics: { ... }`](http://facebook.github.io/react/docs/component-specs.html#statics) | Static methods |
| [`displayName: "..."`](http://facebook.github.io/react/docs/component-specs.html#displayname) | Automatically filled by JSX |
{:.greycode.no-head}
## Lifecycle ```jsx
this.forceUpdate()
```
```jsx
this.setState({ ... })
```
```jsx
this.state
this.props
```
These methods and properies are available for `Component` instances. See: [Component API](http://facebook.github.io/react/docs/component-api.html)
Lifecycle
---------
{: .-two-column}
### Mounting ### Mounting
Before initial rendering occurs. Add your DOM stuff on didMount (events, timers, etc). See [reference](http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount).
| `componentWillMount()` | Before rendering (no DOM yet) | | Method | Description |
| `componentDidMount()` | After rendering | | --- | --- |
{:.greycode.no-head.lc} | `constructor` _(props)_ | Before rendering [#](https://facebook.github.io/react/docs/react-component.html#constructor) |
| `componentWillMount()` | _Don't use this_ [#](https://facebook.github.io/react/docs/react-component.html#componentwillmount) |
| `render()` | Render [#](https://facebook.github.io/react/docs/react-component.html#render) |
| `componentDidMount()` | After rendering (DOM available) [#](https://facebook.github.io/react/docs/react-component.html#componentdidmount) |
| --- | --- |
| `componentWillUnmount()` | Before DOM removal [#](https://facebook.github.io/react/docs/react-component.html#componentwillunmount) |
<br> Set initial the state on `constructor()`.
Add DOM event handlers, timers (etc) on `componentDidMount()`, then remove them on `componentWillUnmount()`.
### Updating ### Updating
Called when parents change properties and `.setState()`. These are not called for initial renders. See [reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
| `componentWillReceiveProps`*(newProps={})* | Use `setState()` here | | Method | Description |
| `shouldComponentUpdate`*(newProps={}, newState={})* | Skips `render()` if returns false | | --- | --- |
| `componentWillUpdate`*(newProps={}, newState={})* | Can't use `setState()` here | | `componentWillReceiveProps` *(newProps)* | Use `setState()` here |
| `componentDidUpdate`*(prevProps={}, prevState={})* | Operate on the DOM here | | `shouldComponentUpdate` *(newProps, newState)* | Skips `render()` if returns false |
{:.greycode.no-head.lc} | `componentWillUpdate` *(newProps, newState)* | Can't use `setState()` here |
| `render()` | Render |
| `componentDidUpdate` *(prevProps, prevState)* | Operate on the DOM here |
<br> Called when parents change properties and `.setState()`. These are not called for initial renders. See: [Reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
### Unmounting DOM nodes
Clear your DOM stuff here (probably done on didMount). See [reference](http://facebook.github.io/react/docs/component-specs.html#unmounting-componentwillunmount). ---------
{: .-two-column}
| `componentWillUnmount()` | Invoked before DOM removal |
{:.greycode.no-head.lc}
<style>
table.lc { table-layout: fixed; }
table.lc tr>:nth-child(1) { width: 50%; }
table.lc tr>:nth-child(2) { text-align: right; }
</style>
<br>
### Example: loading data
See [initial AJAX data](http://facebook.github.io/react/tips/initial-ajax.html).
```js
React.createClass({
componentDidMount: function () {
$.get(this.props.url, function (data) {
this.setState(data);
}.bind(this));
},
render: function () {
return <CommentList data={this.state.data} />
}
});
```
## DOM nodes
### References ### References
Allows access to DOM nodes. See [References](http://facebook.github.io/react/docs/more-about-refs.html).
```html ```jsx
<input ref="myInput"> class MyComponent extends React.Component {
``` render () {
{:.light} return <div>
<input ref={el => this.input = el} />
</div>
}
```js componentDidMount () {
this.refs.myInput this.input.focus()
ReactDOM.findDOMNode(this.refs.myInput).focus() }
ReactDOM.findDOMNode(this.refs.myInput).value
```
### DOM Events
Add attributes like `onChange`. See [events](https://facebook.github.io/react/docs/events.html).
```html
<input type="text"
value={this.state.value}
onChange={this.handleChange} />
```
{:.light}
```js
handleChange: function(event) {
this.setState({ value: event.target.value });
} }
``` ```
{: data-line="4,9"}
### Two-way binding Allows access to DOM nodes. See: [Refs and the DOM](https://facebook.github.io/react/docs/refs-and-the-dom.html)
Use [LinkedStateMixin](http://facebook.github.io/react/docs/two-way-binding-helpers.html) for easier two-way binding.
### DOM Events
```jsx
class MyComponent extends React.Component {
render () {
<input type="text"
value={this.state.value}
onChange={event => this.onChange(event)} />
}
onChange (event) {
this.setState({ value: event.target.vlaue })
}
}
```
{: data-line="5,9"}
Pass functions to attributes like `onChange`. See: [Events](https://facebook.github.io/react/docs/events.html)
## Other features
### Transfering props
```html ```html
Email: <input type="text" valueLink={this.linkState('email')} /> <VideoPlayer src="video.mp4" />
``` ```
{:.light} {: .-setup}
```jsx
class VideoPlayer extends React.Component {
render () {
return <VideoEmbed {...this.props} />
}
}
```
{: data-line="3"}
Propagates `src="..."` down to the sub-component.
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html).
### Top-level API
```jsx
React.createClass({ ... })
React.isValidElement(c)
```
```jsx
ReactDOM.render(<Component />, domnode, [callback])
ReactDOM.unmountComponentAtNode(domnode)
```
```jsx
ReactDOMServer.renderToString(<Component />)
ReactDOMServer.renderToStaticMarkup(<Component />)
```
JSX patterns
------------
{: .-two-column}
### Style shorthand
```jsx
var style = { height: 10 }
return <div style={style}></div>
```
```jsx
return <div style={{ margin: 0, padding: 0 }}></div>
```
See: [Inline styles](https://facebook.github.io/react/tips/inline-styles.html)
### Inner HTML
```jsx
function markdownify() { return "<p>...</p>"; }
<div dangerouslySetInnerHTML={{__html: markdownify()}} />
```
See: [Dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html)
### Lists
```jsx
class TodoList extends React.Component {
render () {
const { items } = this.props
return <ul>
{items.map(item =>
<TodoItem item={item} key={item.key} />)}
</ul>
}
}
```
{: data-line="6,7"}
Always supply a `key` property.
### Conditionals
```jsx
<div>
{showPopup
? <Popup />
: null}
</div>
```
Property validation
-------------------
{: .-three-column}
### PropTypes
```js ```js
React.createClass({ import PropTypes from 'prop-types'
mixins: [React.addons.LinkedStateMixin]
});
``` ```
{: .-setup}
```js See: [Typechecking with PropTypes](https://facebook.github.io/react/docs/typechecking-with-proptypes.html)
this.state.email
```
## Property validation | PropType | Description |
| --- | --- |
| `any` | Anything |
| --- | --- |
| `string` | |
| `number` | |
| `func` | Function |
| `bool` | True or false |
| --- | --- |
| `oneOf`_(any)_ | Enum types |
| `oneOfType`_(type array)_ | Union |
| --- | --- |
| `array` | |
| `arrayOf`_(...)_ | |
| --- | --- |
| `object` | |
| `objectOf`_(...)_ | Object with values of a certain type |
| `instanceOf`_(...)_ | Instance of a class |
| `shape`_(...)_ | |
| --- | --- |
| `element` | React element |
| `node` | DOM node |
| --- | --- |
| `.isRequired` | Required |
### Basic types ### Basic types
Primitive types: `.string`, `.number`, `.func`, and `.bool`. See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
```js ```jsx
React.createClass({ MyComponent.propTypes = {
propTypes: { email: PropTypes.string,
email: React.PropTypes.string, seats: PropTypes.number,
seats: React.PropTypes.number, callback: PropTypes.func,
settings: React.PropTypes.object, isClosed: PropTypes.bool,
callback: React.PropTypes.func, any: PropTypes.any
isClosed: React.PropTypes.bool, }
any: React.PropTypes.any,
}
});
``` ```
### Required types ### Required types
Add `.isRequired`.
```js ```jsx
propTypes: { MyCo.propTypes = {
requiredFunc: React.PropTypes.func.isRequired, name: PropTypes.string.isRequired
requiredAny: React.PropTypes.any.isRequired, }
``` ```
### React elements ### Elements
Use `.element`, `.node`.
```js ```jsx
propTypes: { MyCo.propTypes = {
element: React.PropTypes.element, // react element // React element
node: React.PropTypes.node, // num, string, element element: PropTypes.element,
// ...or array of those
// num, string, element, or an array of those
node: PropTypes.node
}
``` ```
### Enumerables ### Enumerables (oneOf)
Use `.oneOf`, `.oneOfType`.
``` ```jsx
propTypes: { MyCo.propTypes = {
enum: React.PropTypes.oneOf(['M','F']), // enum direction: PropTypes.oneOf([
union: React.PropTypes.oneOfType([ // any 'left', 'right'
React.PropTypes.string, ])
React.PropTypes.number ]), }
``` ```
### Arrays and objects ### Arrays and objects
Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
```js ```jsx
propTypes: { MyCo.propTypes = {
array: React.PropTypes.array, list: PropTypes.array,
arrayOf: React.PropTypes.arrayOf(React.PropTypes.number), ages: PropTypes.arrayOf(PropTypes.number),
object: React.PropTypes.object, user: PropTypes.object,
objectOf: React.PropTypes.objectOf(React.PropTypes.number), user: PropTypes.objectOf(PropTypes.number),
message: PropTypes.instanceOf(Message)
message: React.PropTypes.instanceOf(Message), }
object2: React.PropTypes.shape({
color: React.PropTypes.string,
size: React.PropTypes.number
}),
``` ```
### Custom validation ```jsx
Supply your own function. MyCo.propTypes = {
user: PropTypes.shape({
name: PropTypes.string,
age: PropTypes.number
})
}
```
```js Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
propTypes: {
customProp: function(props, propName, componentName) { ### Custom validation
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!'); ```jsx
MyCo.propTypes = {
customProp: (props, key, componentName) => {
if (!/matchme/.test(props[key])) {
return new Error('Validation failed!')
} }
} }
} }
``` ```
## Other features Examples
--------
{: .-left-reference}
### Class set ### Basic example
Manipulate DOM classes with [classnames](https://www.npmjs.org/package/classnames), previously known as `React.addons.classSet`. See [Class set](http://facebook.github.io/react/docs/class-name-manipulation.html).
```js ```jsx
var cx = require('classnames'); import React from 'react'
import ReactDOM from 'react-dom'
render: function() {
var classes = cx({
'message': true,
'message-important': this.props.isImportant,
'message-read': this.props.isRead
});
return <div className={classes}>Great Scott!</div>;
}
``` ```
### Propagating properties ```jsx
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html). class Hello extends React.Component {
render () {
```html return <div className='message-box'>
<VideoPlayer src="video.mp4" /> Hello {this.props.name}
``` </div>
{:.light}
```js
var VideoPlayer = React.createClass({
render: function() {
/* propagates src="..." down to this sub component */
return <VideoEmbed {...this.props} controls='false' />;
} }
});
```
### Mixins
See [addons](https://facebook.github.io/react/docs/addons.html) for some built-in mixins.
```js
var SetIntervalMixin = {
componentWillMount: function() { .. }
}
```
{:.light}
```js
var TickTock = React.createClass({
mixins: [SetIntervalMixin]
} }
``` ```
## [Top level API](https://facebook.github.io/react/docs/top-level-api.html) ```jsx
const el = document.body
```js ReactDOM.render(<Hello name='John' />, el)
React.createClass({ ... })
React.isValidElement(c)
ReactDOM.findDOMNode(c) // 0.14+
ReactDOM.render(<Component />, domnode, [callback]) // 0.14+
ReactDOM.unmountComponentAtNode(domnode) // 0.14+
ReactDOMServer.renderToString(<Component />) // 0.14+
ReactDOMServer.renderToStaticMarkup(<Component />) // 0.14+
``` ```
## JSX patterns Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output)).
### Style shorthand ### Try it
See [inline styles](https://facebook.github.io/react/tips/inline-styles.html).
```js <iframe src="http://jsbin.com/yafixat/edit?js,output" height="400"></iframe>
var style = { backgroundImage: 'url(x.jpg)', height: 10 };
return <div style={style}></div>;
```
### InnerHTML [Open in jsbin](http://jsbin.com/yafixat/edit?js,output)
See [dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html). {: target="_blank"}
```js Also see
function markdownify() { return "<p>...</p>"; } --------
<div dangerouslySetInnerHTML={{__html: markdownify()}} /> {: .-one-column}
```
### Lists * This reference was made for React v15.
* [React v0.14 cheatsheet](react@0.14.html) _Legacy version_
* [React website](http://facebook.github.io/react) _facebook.github.io_
{:.-also-see}
```js
var TodoList = React.createClass({
render: function() {
function item(itemText) {
return <li>{itemText}</li>;
};
return <ul>{this.props.items.map(item)}</ul>;
}
});
```
## See also
* [Animations](http://facebook.github.io/react/docs/animation.html)
{%endraw%} {%endraw%}

416
react@0.14.md Normal file
View File

@ -0,0 +1,416 @@
---
title: React.js
category: React
layout: default-ad
---
{%raw%}
Use the [React.js jsfiddle](http://jsfiddle.net/reactjs/69z2wepo/) to start hacking. (or the unofficial [jsbin](http://jsbin.com/yafixat/edit?js,output))
{:.brief-intro.center}
```js
var Component = React.createClass({
render: function () {
return <div>Hello {this.props.name}</div>;
}
});
```
```js
ReactDOM.render(<Component name="John" />, document.body);
```
{:.light}
## Nesting
Nest components to separate concerns. See [multiple components](http://facebook.github.io/react/docs/multiple-components.html).
{:.center}
```js
var UserAvatar = React.createClass({...});
var UserProfile = React.createClass({...});
```
{:.light}
```js
var Info = React.createClass({
render() {
return <div>
<UserAvatar src={this.props.avatar} />
<UserProfile username={this.props.username} />
</div>;
}
});
```
## States & Properties
Use [props](https://facebook.github.io/react/docs/tutorial.html#using-props) (`this.props`) to access parameters passed from the parent.
Use [states](https://facebook.github.io/react/docs/tutorial.html#reactive-state) (`this.state`) to manage dynamic data.
{:.center}
```html
<MyComponent fullscreen={true} />
```
{:.light}
```js
// props
this.props.fullscreen //=> true
// state
this.setState({ username: 'rstacruz' });
this.replaceState({ ... });
this.state.username //=> 'rstacruz'
```
```js
render: function () {
return <div className={this.props.fullscreen ? 'full' : ''}>
Welcome, {this.state.username}
</div>;
}
```
### Setting defaults
Pre-populates `this.state.comments` and `this.props.name`.
```js
React.createClass({
getInitialState: function () {
return { comments: [] };
},
getDefaultProps: function () {
return { name: "Hello" };
}
);
```
## Component API
These are methods available for `Component` instances. See [Component API](http://facebook.github.io/react/docs/component-api.html).
{:.center}
```js
ReactDOM.findDOMNode(c) // 0.14+
React.findDOMNode(c) // 0.13
c.getDOMNode() // 0.12 below
```
{:.light}
```js
c.forceUpdate()
c.isMounted()
c.state
c.props
c.setState({ ... })
c.replaceState({ ... })
c.setProps({ ... }) // for deprecation
c.replaceProps({ ... }) // for deprecation
c.refs
```
### Component specs
Methods and properties you can override. See [component specs](http://facebook.github.io/react/docs/component-specs.html).
| Method | What |
| ---- | ---- |
| [`render()`](http://facebook.github.io/react/docs/component-specs.html#render) | |
| ---- | ---- |
| [`getInitialState()`](http://facebook.github.io/react/docs/component-specs.html#getinitialstate) | |
| [`getDefaultProps()`](http://facebook.github.io/react/docs/component-specs.html#getdefaultprops) | |
| ---- | ---- |
| [`mixins: [ ... ]`](http://facebook.github.io/react/docs/component-specs.html#mixins) | Mixins ... [more](#mixins) |
| [`propTypes: { ... }`](http://facebook.github.io/react/docs/component-specs.html#proptypes) | Validation ... [more](#property-validation) |
| [`statics: { ... }`](http://facebook.github.io/react/docs/component-specs.html#statics) | Static methods |
| [`displayName: "..."`](http://facebook.github.io/react/docs/component-specs.html#displayname) | Automatically filled by JSX |
{:.greycode.no-head}
## Lifecycle
### Mounting
Before initial rendering occurs. Add your DOM stuff on didMount (events, timers, etc). See [reference](http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount).
| `componentWillMount()` | Before rendering (no DOM yet) |
| `componentDidMount()` | After rendering |
{:.greycode.no-head.lc}
<br>
### Updating
Called when parents change properties and `.setState()`. These are not called for initial renders. See [reference](http://facebook.github.io/react/docs/component-specs.html#updating-componentwillreceiveprops).
| `componentWillReceiveProps`*(newProps={})* | Use `setState()` here |
| `shouldComponentUpdate`*(newProps={}, newState={})* | Skips `render()` if returns false |
| `componentWillUpdate`*(newProps={}, newState={})* | Can't use `setState()` here |
| `componentDidUpdate`*(prevProps={}, prevState={})* | Operate on the DOM here |
{:.greycode.no-head.lc}
<br>
### Unmounting
Clear your DOM stuff here (probably done on didMount). See [reference](http://facebook.github.io/react/docs/component-specs.html#unmounting-componentwillunmount).
| `componentWillUnmount()` | Invoked before DOM removal |
{:.greycode.no-head.lc}
<style>
table.lc { table-layout: fixed; }
table.lc tr>:nth-child(1) { width: 50%; }
table.lc tr>:nth-child(2) { text-align: right; }
</style>
<br>
### Example: loading data
See [initial AJAX data](http://facebook.github.io/react/tips/initial-ajax.html).
```js
React.createClass({
componentDidMount: function () {
$.get(this.props.url, function (data) {
this.setState(data);
}.bind(this));
},
render: function () {
return <CommentList data={this.state.data} />
}
});
```
## DOM nodes
### References
Allows access to DOM nodes. See [References](http://facebook.github.io/react/docs/more-about-refs.html).
```html
<input ref="myInput">
```
{:.light}
```js
this.refs.myInput
ReactDOM.findDOMNode(this.refs.myInput).focus()
ReactDOM.findDOMNode(this.refs.myInput).value
```
### DOM Events
Add attributes like `onChange`. See [events](https://facebook.github.io/react/docs/events.html).
```html
<input type="text"
value={this.state.value}
onChange={this.handleChange} />
```
{:.light}
```js
handleChange: function(event) {
this.setState({ value: event.target.value });
}
```
### Two-way binding
Use [LinkedStateMixin](http://facebook.github.io/react/docs/two-way-binding-helpers.html) for easier two-way binding.
```html
Email: <input type="text" valueLink={this.linkState('email')} />
```
{:.light}
```js
React.createClass({
mixins: [React.addons.LinkedStateMixin]
});
```
```js
this.state.email
```
## Property validation
### Basic types
Primitive types: `.string`, `.number`, `.func`, and `.bool`. See [propTypes](http://facebook.github.io/react/docs/reusable-components.html#prop-validation).
```js
React.createClass({
propTypes: {
email: React.PropTypes.string,
seats: React.PropTypes.number,
settings: React.PropTypes.object,
callback: React.PropTypes.func,
isClosed: React.PropTypes.bool,
any: React.PropTypes.any,
}
});
```
### Required types
Add `.isRequired`.
```js
propTypes: {
requiredFunc: React.PropTypes.func.isRequired,
requiredAny: React.PropTypes.any.isRequired,
```
### React elements
Use `.element`, `.node`.
```js
propTypes: {
element: React.PropTypes.element, // react element
node: React.PropTypes.node, // num, string, element
// ...or array of those
```
### Enumerables
Use `.oneOf`, `.oneOfType`.
```
propTypes: {
enum: React.PropTypes.oneOf(['M','F']), // enum
union: React.PropTypes.oneOfType([ // any
React.PropTypes.string,
React.PropTypes.number ]),
```
### Arrays and objects
Use `.array[Of]`, `.object[Of]`, `.instanceOf`, `.shape`.
```js
propTypes: {
array: React.PropTypes.array,
arrayOf: React.PropTypes.arrayOf(React.PropTypes.number),
object: React.PropTypes.object,
objectOf: React.PropTypes.objectOf(React.PropTypes.number),
message: React.PropTypes.instanceOf(Message),
object2: React.PropTypes.shape({
color: React.PropTypes.string,
size: React.PropTypes.number
}),
```
### Custom validation
Supply your own function.
```js
propTypes: {
customProp: function(props, propName, componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
}
```
## Other features
### Class set
Manipulate DOM classes with [classnames](https://www.npmjs.org/package/classnames), previously known as `React.addons.classSet`. See [Class set](http://facebook.github.io/react/docs/class-name-manipulation.html).
```js
var cx = require('classnames');
render: function() {
var classes = cx({
'message': true,
'message-important': this.props.isImportant,
'message-read': this.props.isRead
});
return <div className={classes}>Great Scott!</div>;
}
```
### Propagating properties
See [Transferring props](http://facebook.github.io/react/docs/transferring-props.html).
```html
<VideoPlayer src="video.mp4" />
```
{:.light}
```js
var VideoPlayer = React.createClass({
render: function() {
/* propagates src="..." down to this sub component */
return <VideoEmbed {...this.props} controls='false' />;
}
});
```
### Mixins
See [addons](https://facebook.github.io/react/docs/addons.html) for some built-in mixins.
```js
var SetIntervalMixin = {
componentWillMount: function() { .. }
}
```
{:.light}
```js
var TickTock = React.createClass({
mixins: [SetIntervalMixin]
}
```
## [Top level API](https://facebook.github.io/react/docs/top-level-api.html)
```js
React.createClass({ ... })
React.isValidElement(c)
ReactDOM.findDOMNode(c) // 0.14+
ReactDOM.render(<Component />, domnode, [callback]) // 0.14+
ReactDOM.unmountComponentAtNode(domnode) // 0.14+
ReactDOMServer.renderToString(<Component />) // 0.14+
ReactDOMServer.renderToStaticMarkup(<Component />) // 0.14+
```
## JSX patterns
### Style shorthand
See [inline styles](https://facebook.github.io/react/tips/inline-styles.html).
```js
var style = { backgroundImage: 'url(x.jpg)', height: 10 };
return <div style={style}></div>;
```
### InnerHTML
See [dangerously set innerHTML](https://facebook.github.io/react/tips/dangerously-set-inner-html.html).
```js
function markdownify() { return "<p>...</p>"; }
<div dangerouslySetInnerHTML={{__html: markdownify()}} />
```
### Lists
```js
var TodoList = React.createClass({
render: function() {
function item(itemText) {
return <li>{itemText}</li>;
};
return <ul>{this.props.items.map(item)}</ul>;
}
});
```
## See also
* [Animations](http://facebook.github.io/react/docs/animation.html)
{%endraw%}

183
sass.md
View File

@ -1,10 +1,100 @@
--- ---
title: Sass title: Sass
category: CSS category: CSS
layout: 2017/sheet
--- ---
## Basics
{: .-three-column}
### Variables
```scss
$red: #833;
```
```scss
body {
color: $red;
}
```
### Nesting
```scss
.markdown-body {
p {
color: blue;
}
&:hover {
color: red;
}
}
```
### Comments
```scss
/* Block comments */
// Line comments
```
### Mixins
```scss
@mixin heading-font {
font-family: sans-serif;
font-weight: bold;
}
```
```scss
h1 {
@include heading-font;
}
```
### Mixin properties
```scss
@mixin font-size($n) {
font-size: $n * 1.2em;
}
```
```scss
body {
@include font-size(2);
}
```
### Extend
```scss
.button {
···
}
```
```scss
.push-button {
@extend .button;
}
```
### Composing
```scss
@import './other_sass_file`;
```
The `.scss` or `.sass` extension is optional.
## Color functions ## Color functions
### rgba
```scss ```scss
rgb(100, 120, 140) rgb(100, 120, 140)
rgba(100, 120, 140, .5) rgba(100, 120, 140, .5)
@ -14,7 +104,7 @@ rgba($color, .5)
### Mixing ### Mixing
```scss ```scss
mix($a, $b, 10%) /* 10% a, 90% b */ mix($a, $b, 10%) // 10% a, 90% b
``` ```
### Modifying HSLA ### Modifying HSLA
@ -22,18 +112,24 @@ mix($a, $b, 10%) /* 10% a, 90% b */
```scss ```scss
darken($color, 5%) darken($color, 5%)
lighten($color, 5%) lighten($color, 5%)
```
```scss
saturate($color, 5%) saturate($color, 5%)
desaturate($color, 5%) desaturate($color, 5%)
grayscale($color) grayscale($color)
```
```scss
adjust-hue($color, 15deg) adjust-hue($color, 15deg)
compliment($color) /* like adjust-hue(_, 180deg) */ compliment($color) // like adjust-hue(_, 180deg)
invert($color) invert($color)
```
fade-in($color, .5) /* aka opacify() */ ```scss
fade-out($color, .5) /* aka transparentize() - halves the opacity */ fade-in($color, .5) // aka opacify()
rgba($color, .5) /* sets alpha to .5 */ fade-out($color, .5) // aka transparentize() - halves the opacity
rgba($color, .5) // sets alpha to .5
``` ```
### Getting HSL values ### Getting HSL values
@ -42,28 +138,32 @@ rgba($color, .5) /* sets alpha to .5 */
hue($color) hue($color)
saturation($color) saturation($color)
lightness($color) lightness($color)
alpha($color) /* aka opacity() */ alpha($color) // aka opacity()
``` ```
### Full adjustments ### Adjustments
```scss ```scss
/* Changes by fixed amounts */ // Changes by fixed amounts
adjust-color($color, $blue: 5) adjust-color($color, $blue: 5)
adjust-color($color, $lightness: -30%) /* like darken(_, 30%) */ adjust-color($color, $lightness: -30%) // like darken(_, 30%)
adjust-color($color, $alpha: -0.4) /* like fade-out(_, .4) */ adjust-color($color, $alpha: -0.4) // like fade-out(_, .4)
adjust-color($color, $hue: 30deg) /* like adjust-hue(_, 15deg) */ adjust-color($color, $hue: 30deg) // like adjust-hue(_, 15deg)
```
/* Changes via percentage */ ```scss
// Changes via percentage
scale-color($color, $lightness: 50%) scale-color($color, $lightness: 50%)
```
/* Changes one property completely */ ```scss
// Changes one property completely
change-color($color, $hue: 180deg) change-color($color, $hue: 180deg)
change-color($color, $blue: 250) change-color($color, $blue: 250)
/* Supported: $red $green $blue $hue $saturation $lightness $alpha */
``` ```
Supported: `$red` `$green` `$blue` `$hue` `$saturation` `$lightness` `$alpha`
## Other functions ## Other functions
### Strings ### Strings
@ -71,20 +171,24 @@ change-color($color, $blue: 250)
```scss ```scss
unquote('hello') unquote('hello')
quote(hello) quote(hello)
```
```scss
to-upper-case(hello) to-upper-case(hello)
to-lower-case(hello) to-lower-case(hello)
```
```scss
str-length(hello world) str-length(hello world)
str-slice(hello, 2, 5) /* "ello" - it's 1-based, not 0-based */ str-slice(hello, 2, 5) // "ello" - it's 1-based, not 0-based
str-insert("abcd", "X", 1) /* "Xabcd" */ str-insert("abcd", "X", 1) // "Xabcd"
``` ```
### Units ### Units
```scss ```scss
unit(3em) /* 'em' */ unit(3em) // 'em'
unitless(100px) /* false */ unitless(100px) // false
``` ```
### Numbers ### Numbers
@ -94,27 +198,33 @@ floor(3.5)
ceil(3.5) ceil(3.5)
round(3.5) round(3.5)
abs(3.5) abs(3.5)
```
```scss
min(1, 2, 3) min(1, 2, 3)
max(1, 2, 3) max(1, 2, 3)
```
percentage(.5) /* 50% */ ```scss
random(3) /* 0..3 */ percentage(.5) // 50%
random(3) // 0..3
``` ```
### Misc ### Misc
```scss ```scss
variable-exists(red) /* checks for $red */ variable-exists(red) // checks for $red
mixin-exists(red-text) /* checks for @mixin red-text */ mixin-exists(red-text) // checks for @mixin red-text
function-exists(redify) function-exists(redify)
```
```scss
global-variable-exists(red) global-variable-exists(red)
``` ```
```scss ```scss
selector-append('.menu', 'li', 'a') /* .menu li a */ selector-append('.menu', 'li', 'a') // .menu li a
selector-nest('.menu', '&:hover li') /* .menu:hover li */ selector-nest('.menu', '&:hover li') // .menu:hover li
selector-extend(...) selector-extend(...)
selector-parse(...) selector-parse(...)
selector-replace(...) selector-replace(...)
@ -123,10 +233,14 @@ selector-unify(...)
## Feature checks ## Feature checks
### Feature check
```scss ```scss
feature-exists(global-variable-shadowing) feature-exists(global-variable-shadowing)
``` ```
### Features
* global-variable-shadowing * global-variable-shadowing
* extend-selector-pseudoclass * extend-selector-pseudoclass
* units-level-3 * units-level-3
@ -175,7 +289,9 @@ $i: 6;
} }
``` ```
## Conditionals ## Other features
### Conditionals
```scss ```scss
@if $position == 'left' { @if $position == 'left' {
@ -187,29 +303,29 @@ $i: 6;
} }
``` ```
## Interpolation ### Interpolation
```scss ```scss
.#{$klass} { ... } /* Class */ .#{$klass} { ... } // Class
call($function-name) /* Functions */ call($function-name) // Functions
@media #{$tablet} @media #{$tablet}
font: #{$size}/#{$line-height} font: #{$size}/#{$line-height}
url("#{$background}.jpg") url("#{$background}.jpg")
``` ```
## Lists ### Lists
```scss ```scss
$list: (a b c); $list: (a b c);
nth($list, 1) /* starts with 1 */ nth($list, 1) // starts with 1
length($list) length($list)
@each $item in $list { ... } @each $item in $list { ... }
``` ```
## Maps ### Maps
```scss ```scss
$map: (key1: value1, key2: value2, key3: value3); $map: (key1: value1, key2: value2, key3: value3);
@ -217,7 +333,8 @@ $map: (key1: value1, key2: value2, key3: value3);
map-get($map, key1) map-get($map, key1)
``` ```
## Reference ## See also
{: .-one-column}
- <http://sass-lang.com/documentation/Sass/Script/Functions.html> - <http://sass-lang.com/documentation/Sass/Script/Functions.html>
- <http://sass-lang.com/documentation/file.SASS_REFERENCE.html#sassscript> - <http://sass-lang.com/documentation/file.SASS_REFERENCE.html#sassscript>

628
sh.md
View File

@ -1,261 +1,575 @@
--- ---
title: Bash scripting title: Bash scripting
category: CLI category: CLI
layout: 2017/sheet
ads: true
--- ---
### Pattern substitution Getting started
---------------
{: .-three-column}
STR=/path/to/foo.c ### Example
echo ${STR%.c} #=> "/path/to/foo" ```bash
echo ${STR%.c}.o #=> "/path/to/foo.o" #!/usr/bin/env bash
echo ${STR##*.} #=> "c" (extension)
BASE=${STR##*/} #=> "foo.c" (basepath) NAME="John"
DIR=${SRC%$BASE} #=> "/path/to" echo "Hello $NAME!"
```
### Substitutions by regex ### Variables
echo ${STR/hi/hello} # Replace first match ```bash
echo ${STR//hi/hello} # Replace all matches NAME="John"
echo ${STR/#hi/hello} # ^hi echo $NAME
echo ${STR/%hi/hello} # hi$ echo "$NAME"
echo "${NAME}!"
```
echo "${STR:0:3}" # .substr(0, 3) -- position, length ### String quotes
echo "${STR:-3:3}" # Negative position = from the right
echo ${#line} # Length of $line ```bash
NAME="John"
echo "Hi $NAME" #=> Hi John
echo 'Hi $NAME' #=> Hi $NAME
```
[ -z "$CC" ] && CC=gcc # CC ||= "gcc" assignment ### Shell execution
${CC:=gcc} # $CC || "gcc"
${CC:-gcc} # same as above
### Reading input ```bash
echo "I'm in $(pwd)"
echo "I'm in `pwd`"
# Same
```
echo -n "Proceed? [y/n]: " See [Command substitution](http://wiki.bash-hackers.org/syntax/expansion/cmdsubst)
read ans
echo $ans
read -n 1 ans # Just one character ### Conditional execution
```bash
git commit && git push
git commit || echo "Commit failed"
```
### Functions
{: id='functions-example'}
```bash
get_name() {
echo "John"
}
echo "You are $(get_name)"
```
See: [Functions](#functions)
### Conditionals
{: id='conditionals-example'}
```bash
if [ -z "$string" ]; then
echo "String is empty"
elsif [ -n "$string" ]; then
echo "String is not empty"
fi
```
See: [Conditionals](#conditionals)
### Strict mode
```bash
set -euo pipefail
IFS=$'\n\t'
```
See: [Unofficial bash strict mode](http://redsymbol.net/articles/unofficial-bash-strict-mode/)
### Brace expansion
```bash
echo {A,B}.js
```
| `{A,B}` | Same as `A B` |
| `{A,B}.js` | Same as `A.js B.js` |
| `{1..5}` | Same as `1 2 3 4 5` |
See: [Brace expansion](http://wiki.bash-hackers.org/syntax/expansion/brace)
Parameter expansions
--------------------
{: .-three-column}
### Basics
```bash
name="John"
echo ${name}
echo ${name/J/j} #=> "john" (substitution)
echo ${name:0:2} #=> "jo" (slicing)
echo ${food:-Cake} #=> $food or "Cake"
```
```bash
length=2
echo ${name:0:length} #=> "jo"
```
See: [Parameter expansion](http://wiki.bash-hackers.org/syntax/pe)
```bash
STR="/path/to/foo.cpp"
echo ${STR%.cpp} # /path/to/foo
echo ${STR%.cpp}.o # /path/to/foo.o
echo ${STR##*.} # cpp (extension)
echo ${STR##*/} # foo.cpp (basepath)
echo ${STR#*/} # path/to/foo.cpp
echo ${STR##*/} # foo.cpp
echo ${STR/foo/bar} # /path/to/bar.cpp
```
```bash
STR="Hello world"
echo ${STR:6:5} # "world"
echo ${STR:-5:5} # "world"
```
```bash
SRC="/path/to/foo.cpp"
BASE=${STR##*/} #=> "foo.cpp" (basepath)
DIR=${SRC%$BASE} #=> "/path/to" (dirpath)
```
### Substitution
| Code | Description |
| --- | --- |
| `${FOO%suffix}` | Remove suffix |
| `${FOO#prefix}` | Remove prefix |
| --- | --- |
| `${FOO%%suffix}` | Remove long suffix |
| `${FOO##prefix}` | Remove long prefix |
| --- | --- |
| `${FOO/from/to}` | Replace first match |
| `${FOO//from/to}` | Replace all |
| --- | --- |
| `${FOO/%from/to}` | Replace suffix |
| `${FOO/#from/to}` | Replace prefix |
### Substrings
| `${FOO:0:3}` | Substring _(position, length)_ |
| `${FOO:-3:3}` | Substring from the right |
### Length
| `${#FOO}` | Length of `$FOO` |
### Default values
| `${FOO:-val}` | `$FOO`, or `val` if not set |
| `${FOO:=val}` | Set `$FOO` to `val` if not set |
| `${FOO:+val}` | `val` if `$FOO` is set |
| `${FOO:?message}` | Show error message ande xit if `$FOO` is not set |
The `:` is optional (eg, `${FOO=word}` works)
Loops Loops
----- -----
{: .-three-column}
### Basic for loop ### Basic for loop
for i in /etc/rc.*; do ```bash
echo $i for i in /etc/rc.*; do
done echo $i
done
```
### Ranges ### Ranges
for i in {1..5}; do ```bash
echo "Welcome $i" for i in {1..5}; do
done echo "Welcome $i"
done
```
### Reading lines ### Reading lines
cat file.txt | while read line; do ```bash
echo $line cat file.txt | while read line; do
done echo $line
done
```
### Forever
```bash
while true; do
···
done
```
Functions Functions
--------- ---------
{: .-three-column}
### Defining functions ### Defining functions
myfunc() { ... } ```bash
fuction myfunc { ... } myfunc() {
fuction myfunc() { ... } echo "hello $1"
}
```
### Returning strings ```bash
# Same as above (alternate syntax)
function myfunc() {
echo "hello $1"
}
```
myfunc() { ```bash
local myresult='some value' myfunc "John"
echo $myresult ```
}
result=$(myfunc) ### Returning values
### Errors ```bash
myfunc() {
local myresult='some value'
echo $myresult
}
```
myfunc() { return 1; } ```bash
result=$(myfunc)
```
### Raising errors
```bash
myfunc() {
return 1
}
```
```bash
if myfunc; then
echo "success"
else
echo "failure"
fi
```
### Arguments ### Arguments
$# # Number of arguments | Expression | Description |
$* # All args | --- | --- |
$1 # First argument | `$#` | Number of arguments |
| `$*` | All arguments |
| `$@` | All arguments, starting from first |
| `$1` | First argument |
Ifs - files See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).
-----------
# File conditions Conditionals
if [ -a FILE ]; then # -e exists -d directory -f file ------------
fi # -r readable -w writeable -x executable {: .-three-column}
# -h symlink -s size > 0
# File comparisons ### Conditions
if [ FILE1 -nt FILE2 ] # -nt 1 more recent than 2
# -ot 2 more recent than 1
# -ef same files
Ifs | Condition | Description |
--- | --- | --- |
| `[ -z STRING ]` | Empty string |
| `[ -n STRING ]` | Not empty string |
| --- | --- |
| `[ NUM -eq NUM ]` | Equal |
| `[ NUM -ne NUM ]` | Not equal |
| `[ NUM -lt NUM ]` | Less than |
| `[ NUM -le NUM ]` | Less than or equal |
| `[ NUM -gt NUM ]` | Greater than |
| `[ NUM -ge NUM ]` | Greater than or equal |
| --- | --- |
| `[[ STRING =~ STRING ]]` | Regexp |
| --- | --- |
| `(( NUM < NUM ))` | Numeric conditions |
# String | Condition | Description |
if [ -z STRING ] # empty? | --- | --- |
if [ -n STRING ] # not empty? | `[ -o noclobber ]` | If OPTIONNAME is enabled |
| --- | --- |
| `[ ! EXPR ]` | Not |
| `[ X ] && [ Y ]` | And |
| `[ X ] || [ Y ]` | Or |
# Numeric ### File conditions
if [ $? -eq 0 ] # -eq -ne -lt -le -gt -ge
# $? is exit status by the way
# Etc | Condition | Description |
if [ -o noclobber ] # if OPTIONNAME is enabled | --- | --- |
if [ ! EXPR ] # not | `[ -e FILE ]` | Exists |
if [ ONE -a TWO ] # and | `[ -r FILE ]` | Readable |
if [ ONE -o TWO ] # or | `[ -h FILE ]` | Symlink |
| `[ -d FILE ]` | Directory |
| `[ -w FILE ]` | Writable |
| `[ -s FILE ]` | Size is > 0 bytes |
| `[ -f FILE ]` | File |
| `[ -x FILE ]` | Executable |
| --- | --- |
| `[ FILE1 -nt FILE2 ]` | 1 is more recent than 2 |
| `[ FILE1 -ot FILE2 ]` | 2 is more recent than 1 |
| `[ FILE1 -ef FILE2 ]` | Same files |
# Regex ### Example
if [[ "A" =~ "." ]]
### Numeric comparisons ```bash
# String
if [ -z "$string" ]; then
echo "String is empty"
elsif [ -n "$string" ]; then
echo "String is not empty"
fi
```
if (( $a < $b )) ```bash
# Combinations
if [ X ] && [ Y ]; then
...
fi
```
### Unset variables ```bash
# Regex
if [[ "A" =~ "." ]]
```
Assume `$FOO` is not set. Doing *this* will result in *that*: ```bash
if (( $a < $b ))
```
${FOO:-word} # Returns word ```bash
${FOO:+word} # Returns empty, or word if set if [ -e "file.txt" ]; then
${FOO:=word} # Sets parameter to word, returns word echo "file exists"
${FOO:?message} # Echoes message and exits fi
```
${FOO=word} # : is optional in all of the above
Numeric calculations
--------------------
$((RANDOM%=200)) # Random number 0..200
$((a + 200)) # $ is optional
Arrays Arrays
------ ------
# Declaring using declare -a ### Defining arrays
declare -a Fruits=('Apple' 'Banana' 'Orange')
Fruits[0]="Apple" ```bash
Fruits[1]="Banana" Fruits=('Apple' 'Banana' 'Orange')
Fruits[2]="Orange" ```
echo ${Fruits[0]} # Element #0 ```bash
echo ${Fruits[@]} # All elements, space-separated Fruits[0]="Apple"
echo ${#Fruits[@]} # Number of elements Fruits[1]="Banana"
echo ${#Fruits} # String length of the 1st element Fruits[2]="Orange"
echo ${#Fruits[3]} # String length of the Nth element ```
echo ${Fruits[@]:3:2} # Range (from position 3, length 2)
### Working with arrays
```bash
echo ${Fruits[0]} # Element #0
echo ${Fruits[@]} # All elements, space-separated
echo ${#Fruits[@]} # Number of elements
echo ${#Fruits} # String length of the 1st element
echo ${#Fruits[3]} # String length of the Nth element
echo ${Fruits[@]:3:2} # Range (from position 3, length 2)
```
### Operations ### Operations
Fruits=("${Fruits[@]}" "Watermelon") # Push ```bash
Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match Fruits=("${Fruits[@]}" "Watermelon") # Push
unset Fruits[2] # Remove one item Fruits=( ${Fruits[@]/Ap*/} ) # Remove by regex match
Fruits=("${Fruits[@]}") # Duplicate unset Fruits[2] # Remove one item
Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate Fruits=("${Fruits[@]}") # Duplicate
lines=(`cat "logfile"`) # Read from file Fruits=("${Fruits[@]}" "${Veggies[@]}") # Concatenate
lines=(`cat "logfile"`) # Read from file
```
### Iteration ### Iteration
for i in "${arrayName[@]}"; do ```bash
echo $i for i in "${arrayName[@]}"; do
done echo $i
done
```
Misc crap Options
--------- -------
command -V cd #=> "cd is a function/alias/whatever"
### Options ### Options
set -o noclobber # Avoid overlay files (echo "hi" > foo) ```bash
set -o errexit # Used to exit upon error, avoiding cascading errors set -o noclobber # Avoid overlay files (echo "hi" > foo)
set -o pipefail # Unveils hidden failures set -o errexit # Used to exit upon error, avoiding cascading errors
set -o nounset # Exposes unset variables set -o pipefail # Unveils hidden failures
set -o nounset # Exposes unset variables
```
### Glob options ### Glob options
set -o nullglob # Non-matching globs are removed ('*.foo' => '') ```bash
set -o failglob # Non-matching globs throw errors set -o nullglob # Non-matching globs are removed ('*.foo' => '')
set -o nocaseglob # Case insensitive globs set -o failglob # Non-matching globs throw errors
set -o globdots # Wildcards match dotfiles ("*.sh" => ".foo.sh") set -o nocaseglob # Case insensitive globs
set -o globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb') set -o globdots # Wildcards match dotfiles ("*.sh" => ".foo.sh")
set -o globstar # Allow ** for recursive matches ('lib/**/*.rb' => 'lib/a/b/c.rb')
```
set GLOBIGNORE as a colon-separated list of patterns to be removed from glob Set `GLOBIGNORE` as a colon-separated list of patterns to be removed from glob
matches. matches.
Miscellaneous
-------------
### Numeric calculations
```bash
$((a + 200)) # Add 200 to $a
```
```bash
$((RANDOM%=200)) # Random number 0..200
```
### Subshells
```bash
(cd somedir; echo "I'm now in $PWD")
pwd # still in first directory
```
### Redirection
```bash
python hello.py > output.txt # stdout to (file)
python hello.py >> output.txt # stdout to (file), append
python hello.py 2> error.log # stderr to (file)
python hello.py 2>&1 # stderr to stdout
python hello.py 2>/dev/null # stderr to (null)
```
```bash
python hello.py < foo.txt
```
### Inspecting commands
```bash
command -V cd
#=> "cd is a function/alias/whatever"
```
### Trap errors ### Trap errors
trap 'echo Error at about $LINENO' ERR ```bash
trap 'echo Error at about $LINENO' ERR
```
or or
traperr() { ```bash
echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}" traperr() {
} echo "ERROR: ${BASH_SOURCE[1]} at about ${BASH_LINENO[0]}"
}
set -o errtrace set -o errtrace
trap traperr ERR trap traperr ERR
```
### Case/switch ### Case/switch
case $1 in ```bash
start | up) case "$1" in
vagrant up start | up)
;; vagrant up
;;
*) *)
echo "Usage: $0 {start|stop|ssh}" echo "Usage: $0 {start|stop|ssh}"
;; ;;
esac esac
```
### Source relative ### Source relative
source "${0%/*}/../share/foo.sh" ```bash
source "${0%/*}/../share/foo.sh"
```
### printf ### printf
printf "Hello %s, I'm %s" Sven Olga ```bash
printf "Hello %s, I'm %s" Sven Olga
#=> "Hello Sven, I'm Olga
```
### Directory of script ### Directory of script
DIR="${0%/*}" ```bash
DIR="${0%/*}"
```
### Getting options ### Getting options
while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in ```bash
-V | --version ) while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
echo $version -V | --version )
exit echo $version
;; exit
-s | --string ) ;;
shift; string=$1 -s | --string )
;; shift; string=$1
-f | --flag ) ;;
flag=1 -f | --flag )
;; flag=1
esac; shift; done ;;
if [[ "$1" == '--' ]]; then shift; fi esac; shift; done
if [[ "$1" == '--' ]]; then shift; fi
```
### Heredoc ### Heredoc
cat <<END ```sh
hello world cat <<END
END hello world
END
```
## Reference ### Reading input
* [Bash-hackers wiki](http://wiki.bash-hackers.org/) (back-hackers.org) ```bash
* [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) (back-hackers.org) echo -n "Proceed? [y/n]: "
read ans
echo $ans
```
```bash
read -n 1 ans # Just one character
```
### Process IDs
| `$?` | PID of last foreground task |
| `$!` | PID of last background task |
| `$$` | PID of shell |
See [Special parameters](http://wiki.bash-hackers.org/syntax/shellvars#special_parameters_and_shell_variables).
## Also see
{: .-one-column}
* [Bash-hackers wiki](http://wiki.bash-hackers.org/) _(bash-hackers.org)_
* [Shell vars](http://wiki.bash-hackers.org/syntax/shellvars) _(bash-hackers.org)_
* [Learn bash in y minutes](https://learnxinyminutes.com/docs/bash/) _(learnxinyminutes.com)_

View File

@ -1,68 +1,73 @@
--- ---
title: Sketch title: Sketch
category: Apps category: Apps
layout: 2017/sheet
--- ---
Shortcuts
---------
{: .-three-column}
### Insert ### Insert
| `V` | vector | | `V` | Vector |
| `P` | pencil | | `P` | Pencil |
| `T` | text | | `T` | Text |
| `L` | line | | `L` | Line |
| `R` | rect | | `R` | Rectangle |
| `O` | oval | | `O` | Oval |
| `U` | rounded | | `U` | Rounded |
{:.shortcuts} {: .-shortcuts}
### Show ### Show
| `^G` | grid | | `^G` | Show grid |
| `^L` | layout | | `^L` | Show layout |
| `^P` | pixels | | `^P` | Show pixels |
| `^H` | selection handles | | `^H` | Show selection handles |
| `^R` | rulers | | `^R` | Show rulers |
{:.shortcuts} {: .-shortcuts}
### Sidebars ### Sidebars
| `⌘⌥1` | toggle left (layers) | | `⌘⌥1` | Toggle left (layers) |
| `⌘⌥2` | toggle right (inspector) | | `⌘⌥2` | Toggle right (inspector) |
| `⌘⌥3` | toggle both | | `⌘⌥3` | Toggle both |
| `⌘.` | presentation | | `⌘.` | Presentation mode |
{:.shortcuts} {: .-shortcuts}
### Zoom ### Zoom
| `⌘0` | 100% | | `⌘0` | 100% |
| `⌘1` | fit to screen | | `⌘1` | Fit to screen |
| `⌘2` | fit selection to screen | | `⌘2` | Fit selection to screen |
| `⌘3` | center selection | | `⌘3` | Center selection |
{:.shortcuts} {: .-shortcuts}
### Arrange ### Arrange
| `⌘⌥ up/dn` | forward or backward | | `⌘⌥↑` _/_ `↓` | Forward or backward |
| `^⌘⌥ up/dn` | front or back | | `^⌘⌥↑` _/_ `↓` | Front or back |
{:.shortcuts} {: .-shortcuts}
### Distribute ### Distribute
| `^⌘H` | horizontal | | `^⌘H` | Horizontal |
| `^⌘V` | vertical | | `^⌘V` | Vertical |
{:.shortcuts} {: .-shortcuts}
### Layers ### Layers
| `⌘R` | rename | | `⌘R` | Rename layer |
| `⌘F` | find | | `⌘F` | Find layer |
| `⌘G` | group | | `⌘G` | Group |
| `⌘⇧G` | ungroup | | `⌘⇧G` | Ungroup |
{:.shortcuts} {: .-shortcuts}
### Font ### Font
| `⌘⌥ +/-` | bigger/smaller | | `⌘⌥ +` _/_ `-` | Bigger/smaller |
| `⌘⇧[` | left align | | `⌘⇧[` | Left align |
| `⌘⇧\` | center align | | `⌘⇧\` | Center align |
| `⌘⇧]` | right align | | `⌘⇧]` | Right align |
{:.shortcuts} {: .-shortcuts}

319
vim.md
View File

@ -1,137 +1,268 @@
--- ---
title: vim title: Vim
category: Vim category: Vim
layout: 2017/sheet
--- ---
* [Digraphs](vim-digraphs.html) Getting started
* [Help text](vim-help.html) ---------------
* [Vimscript](vimscript.html) {: .-three-column}
* [Vim-unite](vim-unite.html)
* [Vim-easyalign](vim-easyalign.html)
* [Vim-rails](vim-rails.html)
Command line ### Exiting
------------ {: .-prime}
<C-r><C-w> # insert current word into the command line | Shortcut | Description |
<C-r>" # paste from " register | --- | --- |
| `:qa` | Close all files |
| `:qa!` | Close all files, abandon changes |
| --- | --- |
| `:w` | Save |
| `:wq` _/_ `:x` | Save and close file |
| --- | --- |
| `:q` | Close file |
| `:q!` | Close file, abandon changes |
| --- | --- |
| `ZZ` | Save and quit |
| `ZQ` | Quit without checking changes |
{: .-shortcuts}
### Navigating
| Shortcut | Description |
| --- | --- |
| `h` `j` `k` `l` | Arrow keys |
| `^u` _/_ `^d` | Page up/page down |
| --- | --- |
| `b` _/_ `w` | Previous/next word |
| `e` _/_ `ge` | Previous/next end of word |
| --- | --- |
| `0` _(zero)_ | Start of line |
| `^` | Start of line _(after whitespace)_ |
| --- | --- |
| `$` | End of line |
| `gg` | First line |
| `G` | Last line |
| --- | --- |
| `:n` | Go to line `n` |
| `nG` | Go to line `n` |
{: .-shortcuts}
### Entering insert mode
| Shortcut | Description |
| --- | --- |
| `a` | Append |
| `i` | Insert |
| `o` | Next line |
| `O` | Previous line |
| --- | --- |
| `s` | Delete char and insert |
| `S` | Delete line and insert |
| `C` | Delete until end of line and insert |
| --- | --- |
| `R` | Replace |
{: .-shortcuts}
### Exiting insert mode
| Shortcut | Description |
| --- | --- |
| `Esc` _/_ `^[` | Exit insert mode |
| `^c` | Exit insert mode, and abort current command |
{: .-shortcuts}
### Clipboard
| Shortcut | Description |
| --- | --- |
| `x` | Delete character |
| --- | --- |
| `dd` | Delete line _(Cut)_ |
| `yy` | Yank line _(Copy)_ |
| --- | --- |
| `p` | Paste |
| `P` | Paste before |
{: .-shortcuts}
### Visual mode
| Shortcut | Description |
| --- | --- |
| `v` | Enter visual mode |
| `V` | Enter visual line mode |
| `^v` | Enter visual block mode |
| --- | --- |
| `d` _/_ `x` | Delete selection |
| `s` | Replace selection |
| `y` | Yank selection _(Copy)_ |
{: .-shortcuts}
Text objects Text objects
------------ ------------
vip # Select paragraph ### Usage
vipipipip # Select more
ap # a paragraph | Shortcut | Description |
ip # inner paragraph | --- | --- |
| `vip` | Select paragraph |
| `vipipipip` | Select more |
| --- | --- |
| `yip` | Yank inner paragraph |
| `yap` | Yank paragraph (including newline) |
| --- | --- |
| `dip` | Delete inner paragraph |
{: .-shortcuts}
ap, ip # Paragraph ### Text objects
aw, iw # Word
as, is # Sentence
ab # A block [( | Shortcut | Description |
aB # A block in [{ | --- | --- |
at # A XML tag block | `ap` | a paragraph |
a[ ( { < # A [], (), or {} block | `ip` | inner paragraph |
a' " ` # A quoted string | --- | --- |
| `ap` `ip` | Paragraph |
| `aw` `iw` | Word |
| `as` `is` | Sentence |
| --- | --- |
| `a[` `a(` `a{` `a<` | A [], (), or {} block |
| `a'` `a"` <code>a`</code> | A quoted string |
| --- | --- |
| `ab` | A block [( |
| `aB` | A block in [{ |
| `at` | A XML tag block |
{: .-shortcuts}
[( [{ [< # previous ( or { or < ### Navigation
]) # next
[m # previous method start | Shortcut | Description |
[M # previous method end | --- | --- |
| `[(` `[{` `[<` | previous `(` or `{` or `<` |
| `])` | next |
| --- | --- |
| `[m` | previous method start |
| `[M` | previous method end |
{: .-shortcuts}
Example:
yip # Yank inner paragraph
yap # Yank paragraph (including newline)
Folds
-----
zo # Open
zO # Open, recursive
zc # Close
zC # Close, recursive
za # Toggle
zA # Toggle, recursive
zv # Open folds for this line
zM # Close all
zR # Open all
zm # Fold more (foldlevel += 1)
zr # Fold less (foldlevel -= 1)
zx # Update
Jumping
-------
^O # Go back to previous location
^I # Go forward
gf # go to file in cursor
Misc Misc
---- ----
. # repeat last command ### Folds
]p # paste under the current indentation level
zz # Center this line | Shortcut | Description |
| --- | --- |
| `zo` _/_ `zO` | Open |
| `zc` _/_ `zC` | Close |
| `za` _/_ `zA` | Toggle |
| --- | --- |
| `zv` | Open folds for this line |
| --- | --- |
| `zM` | Close all |
| `zR` | Open all |
| --- | --- |
| `zm` | Fold more _(foldlevel += 1)_ |
| `zr` | Fold less _(foldlevel -= 1)_ |
| --- | --- |
| `zx` | Update folds |
{: .-shortcuts}
Counters Uppercase ones are recursive (eg, `zO` is open recursively).
--------
^A # increment number ### Jumping
^X # decrement
Windows | Shortcut | Description |
------- | --- | --- |
| `^O` | Go back to previous location |
| `^I` | Go forward |
| --- | --- |
| `gf` | go to file in cursor |
{: .-shortcuts}
z{height}<Cr> # Resize pane to {height} lines tall ### Counters
Tags | `^A` | increment number |
---- | `^X` | decrement |
:tag Classname # Jump to first definition of Classname ### Windows
^] # Jump to definition | `z{height}<Cr>` | Resize pane to `{height}` lines tall |
g] # See all definitions
C-t # Go back to last tag
^O ^I # Back/forward
:tselect Classname # Find definitions of Classname ### Tags
:tjump Classname # Find definitions of Classname (auto-select 1st)
Case | Shortcut | Description |
---- | --- | --- |
| `:tag Classname` | Jump to first definition of Classname |
| --- | --- |
| `^]` | Jump to definition |
| `g]` | See all definitions |
| `^t` | Go back to last tag |
| `^o ^i` | Back/forward |
| --- | --- |
| `:tselect Classname` | Find definitions of Classname |
| `:tjump Classname` | Find definitions of Classname (auto-select 1st) |
{: .-shortcuts}
~ # toggle case (Case => cASE) ### Case
gU # uppercase
gu # lowercase
gUU # uppercase current line (also gUgU) | Shortcut | Description |
guu # lowercase current line (also gugu) | --- | --- |
| `~` | toggle case (Case => cASE) |
| `gU` | uppercase |
| `gu` | lowercase |
| --- | --- |
| `gUU` | uppercase current line (also `gUgU`) |
| `guu` | lowercase current line (also `gugu`) |
{: .-shortcuts}
Marks Do these in visual mode.
-----
`^ # Last position of cursor in insert mode ### Marks
`. # Last change
`` # Last jump
Text alignment | <code>`^</code> | Last position of cursor in insert mode |
-------------- | <code>`.</code> | Last change |
| <code>``</code> | Last jump |
See `:help formatting` ### Misc
| Shortcut | Description |
| --- | --- |
| `.` | repeat last command |
| `]p` | paste under the current indentation level |
| --- | --- |
| `zz` | Center this line |
### Command line
| Shortcut | Description |
| --- | --- |
| `<C-r><C-w>` | insert current word into the command line |
| `<C-r>"` | paste from " register |
### Text alignment
:center [width] :center [width]
:right [width] :right [width]
:left :left
See `:help formatting`
### Calculator ### Calculator
(Insert mode) <C-r>=128/2 <C-r>=128/2
Do this in insert mode.
Also see
--------
{: .-one-column}
* [Digraphs](vim-digraphs.html)
* [Help text](vim-help.html)
* [Vimscript](vimscript.html)
* [Vim-unite](vim-unite.html)
* [Vim-easyalign](vim-easyalign.html)
* [Vim-rails](vim-rails.html)
{: .-also-see}
This reference was made for Vim 8.0.