浏览代码

Add `cd`, `cat`, `ls`, tree structure

Also upgrade Riot, Skeleton, and add HighlightJs.
Weiyi Lou 9 年之前
父节点
当前提交
a6380a9135

文件差异内容过多而无法显示
+ 0 - 0
css/vendor/skeleton.min.css


+ 0 - 427
css/vendor/skeleton/normalize.css

@@ -1,427 +0,0 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- *    user zoom.
- */
-
-html {
-  font-family: sans-serif; /* 1 */
-  -ms-text-size-adjust: 100%; /* 2 */
-  -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
-  margin: 0;
-}
-
-/* HTML5 display definitions
-   ========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-menu,
-nav,
-section,
-summary {
-  display: block;
-}
-
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-
-audio,
-canvas,
-progress,
-video {
-  display: inline-block; /* 1 */
-  vertical-align: baseline; /* 2 */
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
-  display: none;
-  height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
-  display: none;
-}
-
-/* Links
-   ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
-  background-color: transparent;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
-  outline: 0;
-}
-
-/* Text-level semantics
-   ========================================================================== */
-
-/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
- */
-
-abbr[title] {
-  border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
- */
-
-b,
-strong {
-  font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari and Chrome.
- */
-
-dfn {
-  font-style: italic;
-}
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-
-h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
-  background: #ff0;
-  color: #000;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
-  font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
-  font-size: 75%;
-  line-height: 0;
-  position: relative;
-  vertical-align: baseline;
-}
-
-sup {
-  top: -0.5em;
-}
-
-sub {
-  bottom: -0.25em;
-}
-
-/* Embedded content
-   ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-
-img {
-  border: 0;
-}
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
-  overflow: hidden;
-}
-
-/* Grouping content
-   ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
- */
-
-figure {
-  margin: 1em 40px;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-  height: 0;
-}
-
-/**
- * Contain overflow in all browsers.
- */
-
-pre {
-  overflow: auto;
-}
-
-/**
- * Address odd `em`-unit font size rendering in all browsers.
- */
-
-code,
-kbd,
-pre,
-samp {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-
-/* Forms
-   ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
-
-/**
- * 1. Correct color not being inherited.
- *    Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
-  color: inherit; /* 1 */
-  font: inherit; /* 2 */
-  margin: 0; /* 3 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
-  overflow: visible;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
-
-button,
-select {
-  text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- *    and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- *    `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
-  -webkit-appearance: button; /* 2 */
-  cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
-  cursor: default;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-  border: 0;
-  padding: 0;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
-  line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
-  box-sizing: border-box; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
-  height: auto;
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
- *    (include `-moz` to future-proof).
- */
-
-input[type="search"] {
-  -webkit-appearance: textfield; /* 1 */
-  -moz-box-sizing: content-box;
-  -webkit-box-sizing: content-box; /* 2 */
-  box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
-  border: 1px solid #c0c0c0;
-  margin: 0 2px;
-  padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
-  border: 0; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
- */
-
-textarea {
-  overflow: auto;
-}
-
-/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
-  font-weight: bold;
-}
-
-/* Tables
-   ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-td,
-th {
-  padding: 0;
-}

+ 0 - 418
css/vendor/skeleton/skeleton.css

@@ -1,418 +0,0 @@
-/*
-* Skeleton V2.0.4
-* Copyright 2014, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 12/29/2014
-*/
-
-
-/* Table of contents
-––––––––––––––––––––––––––––––––––––––––––––––––––
-- Grid
-- Base Styles
-- Typography
-- Links
-- Buttons
-- Forms
-- Lists
-- Code
-- Tables
-- Spacing
-- Utilities
-- Clearing
-- Media Queries
-*/
-
-
-/* Grid
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.container {
-  position: relative;
-  width: 100%;
-  max-width: 960px;
-  margin: 0 auto;
-  padding: 0 20px;
-  box-sizing: border-box; }
-.column,
-.columns {
-  width: 100%;
-  float: left;
-  box-sizing: border-box; }
-
-/* For devices larger than 400px */
-@media (min-width: 400px) {
-  .container {
-    width: 85%;
-    padding: 0; }
-}
-
-/* For devices larger than 550px */
-@media (min-width: 550px) {
-  .container {
-    width: 80%; }
-  .column,
-  .columns {
-    margin-left: 4%; }
-  .column:first-child,
-  .columns:first-child {
-    margin-left: 0; }
-
-  .one.column,
-  .one.columns                    { width: 4.66666666667%; }
-  .two.columns                    { width: 13.3333333333%; }
-  .three.columns                  { width: 22%;            }
-  .four.columns                   { width: 30.6666666667%; }
-  .five.columns                   { width: 39.3333333333%; }
-  .six.columns                    { width: 48%;            }
-  .seven.columns                  { width: 56.6666666667%; }
-  .eight.columns                  { width: 65.3333333333%; }
-  .nine.columns                   { width: 74.0%;          }
-  .ten.columns                    { width: 82.6666666667%; }
-  .eleven.columns                 { width: 91.3333333333%; }
-  .twelve.columns                 { width: 100%; margin-left: 0; }
-
-  .one-third.column               { width: 30.6666666667%; }
-  .two-thirds.column              { width: 65.3333333333%; }
-
-  .one-half.column                { width: 48%; }
-
-  /* Offsets */
-  .offset-by-one.column,
-  .offset-by-one.columns          { margin-left: 8.66666666667%; }
-  .offset-by-two.column,
-  .offset-by-two.columns          { margin-left: 17.3333333333%; }
-  .offset-by-three.column,
-  .offset-by-three.columns        { margin-left: 26%;            }
-  .offset-by-four.column,
-  .offset-by-four.columns         { margin-left: 34.6666666667%; }
-  .offset-by-five.column,
-  .offset-by-five.columns         { margin-left: 43.3333333333%; }
-  .offset-by-six.column,
-  .offset-by-six.columns          { margin-left: 52%;            }
-  .offset-by-seven.column,
-  .offset-by-seven.columns        { margin-left: 60.6666666667%; }
-  .offset-by-eight.column,
-  .offset-by-eight.columns        { margin-left: 69.3333333333%; }
-  .offset-by-nine.column,
-  .offset-by-nine.columns         { margin-left: 78.0%;          }
-  .offset-by-ten.column,
-  .offset-by-ten.columns          { margin-left: 86.6666666667%; }
-  .offset-by-eleven.column,
-  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }
-
-  .offset-by-one-third.column,
-  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }
-  .offset-by-two-thirds.column,
-  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }
-
-  .offset-by-one-half.column,
-  .offset-by-one-half.columns     { margin-left: 52%; }
-
-}
-
-
-/* Base Styles
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/* NOTE
-html is set to 62.5% so that all the REM measurements throughout Skeleton
-are based on 10px sizing. So basically 1.5rem = 15px :) */
-html {
-  font-size: 62.5%; }
-body {
-  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
-  line-height: 1.6;
-  font-weight: 400;
-  font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #222; }
-
-
-/* Typography
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-h1, h2, h3, h4, h5, h6 {
-  margin-top: 0;
-  margin-bottom: 2rem;
-  font-weight: 300; }
-h1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}
-h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
-h3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }
-h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
-h5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }
-h6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }
-
-/* Larger than phablet */
-@media (min-width: 550px) {
-  h1 { font-size: 5.0rem; }
-  h2 { font-size: 4.2rem; }
-  h3 { font-size: 3.6rem; }
-  h4 { font-size: 3.0rem; }
-  h5 { font-size: 2.4rem; }
-  h6 { font-size: 1.5rem; }
-}
-
-p {
-  margin-top: 0; }
-
-
-/* Links
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-a {
-  color: #1EAEDB; }
-a:hover {
-  color: #0FA0CE; }
-
-
-/* Buttons
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.button,
-button,
-input[type="submit"],
-input[type="reset"],
-input[type="button"] {
-  display: inline-block;
-  height: 38px;
-  padding: 0 30px;
-  color: #555;
-  text-align: center;
-  font-size: 11px;
-  font-weight: 600;
-  line-height: 38px;
-  letter-spacing: .1rem;
-  text-transform: uppercase;
-  text-decoration: none;
-  white-space: nowrap;
-  background-color: transparent;
-  border-radius: 4px;
-  border: 1px solid #bbb;
-  cursor: pointer;
-  box-sizing: border-box; }
-.button:hover,
-button:hover,
-input[type="submit"]:hover,
-input[type="reset"]:hover,
-input[type="button"]:hover,
-.button:focus,
-button:focus,
-input[type="submit"]:focus,
-input[type="reset"]:focus,
-input[type="button"]:focus {
-  color: #333;
-  border-color: #888;
-  outline: 0; }
-.button.button-primary,
-button.button-primary,
-input[type="submit"].button-primary,
-input[type="reset"].button-primary,
-input[type="button"].button-primary {
-  color: #FFF;
-  background-color: #33C3F0;
-  border-color: #33C3F0; }
-.button.button-primary:hover,
-button.button-primary:hover,
-input[type="submit"].button-primary:hover,
-input[type="reset"].button-primary:hover,
-input[type="button"].button-primary:hover,
-.button.button-primary:focus,
-button.button-primary:focus,
-input[type="submit"].button-primary:focus,
-input[type="reset"].button-primary:focus,
-input[type="button"].button-primary:focus {
-  color: #FFF;
-  background-color: #1EAEDB;
-  border-color: #1EAEDB; }
-
-
-/* Forms
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea,
-select {
-  height: 38px;
-  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
-  background-color: #fff;
-  border: 1px solid #D1D1D1;
-  border-radius: 4px;
-  box-shadow: none;
-  box-sizing: border-box; }
-/* Removes awkward default styles on some inputs for iOS */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea {
-  -webkit-appearance: none;
-     -moz-appearance: none;
-          appearance: none; }
-textarea {
-  min-height: 65px;
-  padding-top: 6px;
-  padding-bottom: 6px; }
-input[type="email"]:focus,
-input[type="number"]:focus,
-input[type="search"]:focus,
-input[type="text"]:focus,
-input[type="tel"]:focus,
-input[type="url"]:focus,
-input[type="password"]:focus,
-textarea:focus,
-select:focus {
-  border: 1px solid #33C3F0;
-  outline: 0; }
-label,
-legend {
-  display: block;
-  margin-bottom: .5rem;
-  font-weight: 600; }
-fieldset {
-  padding: 0;
-  border-width: 0; }
-input[type="checkbox"],
-input[type="radio"] {
-  display: inline; }
-label > .label-body {
-  display: inline-block;
-  margin-left: .5rem;
-  font-weight: normal; }
-
-
-/* Lists
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-ul {
-  list-style: circle inside; }
-ol {
-  list-style: decimal inside; }
-ol, ul {
-  padding-left: 0;
-  margin-top: 0; }
-ul ul,
-ul ol,
-ol ol,
-ol ul {
-  margin: 1.5rem 0 1.5rem 3rem;
-  font-size: 90%; }
-li {
-  margin-bottom: 1rem; }
-
-
-/* Code
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-code {
-  padding: .2rem .5rem;
-  margin: 0 .2rem;
-  font-size: 90%;
-  white-space: nowrap;
-  background: #F1F1F1;
-  border: 1px solid #E1E1E1;
-  border-radius: 4px; }
-pre > code {
-  display: block;
-  padding: 1rem 1.5rem;
-  white-space: pre; }
-
-
-/* Tables
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-th,
-td {
-  padding: 12px 15px;
-  text-align: left;
-  border-bottom: 1px solid #E1E1E1; }
-th:first-child,
-td:first-child {
-  padding-left: 0; }
-th:last-child,
-td:last-child {
-  padding-right: 0; }
-
-
-/* Spacing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-button,
-.button {
-  margin-bottom: 1rem; }
-input,
-textarea,
-select,
-fieldset {
-  margin-bottom: 1.5rem; }
-pre,
-blockquote,
-dl,
-figure,
-table,
-p,
-ul,
-ol,
-form {
-  margin-bottom: 2.5rem; }
-
-
-/* Utilities
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.u-full-width {
-  width: 100%;
-  box-sizing: border-box; }
-.u-max-full-width {
-  max-width: 100%;
-  box-sizing: border-box; }
-.u-pull-right {
-  float: right; }
-.u-pull-left {
-  float: left; }
-
-
-/* Misc
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-hr {
-  margin-top: 3rem;
-  margin-bottom: 3.5rem;
-  border-width: 0;
-  border-top: 1px solid #E1E1E1; }
-
-
-/* Clearing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-
-/* Self Clearing Goodness */
-.container:after,
-.row:after,
-.u-cf {
-  content: "";
-  display: table;
-  clear: both; }
-
-
-/* Media Queries
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/*
-Note: The best way to structure the use of media queries is to create the queries
-near the relevant code. For example, if you wanted to change the styles for buttons
-on small devices, paste the mobile query code up in the buttons section and style it
-there.
-*/
-
-
-/* Larger than mobile */
-@media (min-width: 400px) {}
-
-/* Larger than phablet (also point when grid becomes active) */
-@media (min-width: 550px) {}
-
-/* Larger than tablet */
-@media (min-width: 750px) {}
-
-/* Larger than desktop */
-@media (min-width: 1000px) {}
-
-/* Larger than Desktop HD */
-@media (min-width: 1200px) {}

+ 84 - 0
css/vendor/solarized-dark.css

@@ -0,0 +1,84 @@
+/*
+
+Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>
+
+*/
+
+.hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 0.5em;
+  background: #002b36;
+  color: #839496;
+}
+
+.hljs-comment,
+.hljs-quote {
+  color: #586e75;
+}
+
+/* Solarized Green */
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-addition {
+  color: #859900;
+}
+
+/* Solarized Cyan */
+.hljs-number,
+.hljs-string,
+.hljs-meta .hljs-meta-string,
+.hljs-literal,
+.hljs-doctag,
+.hljs-regexp {
+  color: #2aa198;
+}
+
+/* Solarized Blue */
+.hljs-title,
+.hljs-section,
+.hljs-name,
+.hljs-selector-id,
+.hljs-selector-class {
+  color: #268bd2;
+}
+
+/* Solarized Yellow */
+.hljs-attribute,
+.hljs-attr,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-class .hljs-title,
+.hljs-type {
+  color: #b58900;
+}
+
+/* Solarized Orange */
+.hljs-symbol,
+.hljs-bullet,
+.hljs-subst,
+.hljs-meta,
+.hljs-meta .hljs-keyword,
+.hljs-selector-attr,
+.hljs-selector-pseudo,
+.hljs-link {
+  color: #cb4b16;
+}
+
+/* Solarized Red */
+.hljs-built_in,
+.hljs-deletion {
+  color: #dc322f;
+}
+
+.hljs-formula {
+  background: #073642;
+}
+
+.hljs-emphasis {
+  font-style: italic;
+}
+
+.hljs-strong {
+  font-weight: bold;
+}

+ 8 - 5
index.html

@@ -6,13 +6,13 @@
     <meta name="viewport" content="width=device-width, initial-scale=1">
 
     <title>pgsh</title>
-    <meta name="description" content="">
-    <meta name="author" content="">
+    <meta name="description" content="The Parsley Gardens Website!">
+    <meta name="author" content="Weiyi Lou">
 
     <!-- CSS
     –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-    <link rel='stylesheet' type='text/css' href='css/vendor/skeleton/normalize.css' />
-    <link rel='stylesheet' type='text/css' href='css/vendor/skeleton/skeleton.css' />
+    <link rel='stylesheet' type='text/css' href='css/vendor/skeleton.min.css' />
+    <link rel='stylesheet' type='text/css' href='css/vendor/solarized-dark.css' />
     <link rel='stylesheet' type='text/css' href='css/style.css' />
   </head>
   <body>
@@ -21,13 +21,16 @@
     –––––––––––––––––––––––––––––––––––––––––––––––––– -->
     <div class='container'>
       <div class='console-outer'>
-        <div class='console-inner'><terminal-ui shell='pgsh'></terminal-ui></div>
+        <div class='console-inner'>
+          <terminal-ui shell='pgsh'></terminal-ui>
+        </div>
       </div>
     </div>
 
     <!-- Scripts
     –––––––––––––––––––––––––––––––––––––––––––––––––– -->
     <script src='js/vendor/riot+compiler.min.js'></script>
+    <script src='js/vendor/highlight.pack.js'></script>
     <script src='js/pgsh.js'></script>
     <script src='tags/terminal-ui.tag' type='riot/tag'></script>
     <script>riot.mount('*')</script>

+ 207 - 88
js/pgsh.js

@@ -1,11 +1,13 @@
 function pgsh(ev) {
   var self = this
 
+  /**
+   * Terminal UI/Shell Entry Point
+   */
   ev.on('cmd_entered', function(input) {
-    // First word is the command, all others are arguments.
-    var parts = input.trim().split(' ')
-    var command = self.active ? self.active : parts.splice(0, 1).toString()
-    var args = parts
+    var args = input.trim().split(' ')
+    // Use the first argument as a command, or the value of `active`.
+    var command = self.active ? self.active : args.splice(0, 1).toString()
     if (command in self.commands) {
       self[command](args)
     } else if (command) {
@@ -13,49 +15,121 @@ function pgsh(ev) {
     }
   })
 
-  var show = function(text) { ev.trigger('disp_add', text) }
-  var set = function(text) { ev.trigger('disp_set', text) }
-
-  this.prompt = '<span style="color:blueviolet">pgs </span>' +
-    '<span style="color:green">$ </span>'
-  this.prompt_su = '<span style="color:tomato">root </span>' +
-    '<span style="color:red">% </span>'
-  this.welcome = 'Linux parsleygardens.net 3.4.5-6-7-i286 #8 PGS Vimputer ' +
+  /**
+   * Variables and Setup
+   */
+  this.cwd = '/home/pgs'
+  var getPrompt = function() {
+    if (self.su_active) {
+      return '<span style="color:purple">root </span>' +
+      '<span style="color:tomato">' + self.cwd + ' </span>' +
+      '<span style="color:red">% </span>'
+    }
+    return '<span style="color:blueviolet">pgs </span>' +
+      '<span style="color:sienna">' + self.cwd + ' </span>' +
+      '<span style="color:green">$ </span>'
+  }
+  this.prompt = getPrompt()
+  this.welcome = 'Linux parsleygardens.net 3.4.5-6-7-i286 #8 PGS Vimputer' +
     '3.4.56-7 i286\n\n' +
     '~ Welcome to Parsley Gardens! ~\n' +
     '"He maketh me to lie down in green pa..."\n\n' +
     'Type `help` for list of commands\n\n'
+  this.tree = {
+    'bin': {},
+    'etc': {},
+    'home': {
+      'pgs': {
+        'about.md':
+          '# Parsley Gardens\n\nSite created by ** Weiyi Lou ** ' +
+          new Date().getFullYear(),
+        'git.txt':
+          'Code Repository at <a target="_blank"' +
+          'href="https://code.parsleygardens.net/explore/projects">' +
+          'code.parsleygardens.net</a>',
+        'magic.txt': 'slightlymagic.com.au'
+      }
+    },
+    'mnt': {},
+    'root': {
+      'bin': {
+        'destroy.sh':
+          "#!/usr/bin/env bash\n" +
+          "set -euo pipefail\n" +
+          "IFS=$'\\n\\t'\n\n" +
+          "rm -rf /"
+      },
+      'everyday_lost_item_locations_global.sqlite': '',
+      'government-secrets.txt': ''
+    },
+    'usr': {
+      'local': {
+        'bin': {
+          'nothing.txt': 'Really nothing'
+        }
+      }
+    },
+    'var': {
+      'cache': {},
+      'log': {},
+      'run': {}
+    }
+  }
   this.commands = {
-    'about': 'Author Information',
+    'about': 'Author information',
+    'cat': 'Con(cat)enate the contents of a file',
+    'cd': 'Change folder/directory',
     'clear': 'Clears the screen',
-    'version': 'Shell Information',
-    'git': 'Link to Code Repository',
-    'hello': 'Say hello to the computer\nUsage: hello [name]',
-    'magic': 'Link to Artist',
-    'su': 'Gain Phenomenal Cosmic Power',
     'exit': 'Leave the current context',
+    'hello': 'Say hello to the computer\nUsage: hello [name]',
+    'help': 'List commands or view information for one\nUsage: help [command]',
+    'ls': 'List folder contents',
+    'pwd': 'Show the current working directory',
+    'question': 'Displays a question',
     'search': 'Search the Web (with a Duck)\nUsage: search [query]',
-    'questions': 'Answer some questions!',
-    'help': 'List commands or view information for one\nUsage: help [command]'
+    'su': 'Gain Phenomenal Cosmic Power',
+    'version': 'Display shell information'
   }
 
   /**
-   * The Commands
+   * Commands
    */
   this.about = function(args) {
-    show('Site by Weiyi Lou ' + new Date().getFullYear() + '\n')
+    self.cat(['/home/pgs/about.md'])
+  }
+  this.cat = function(args) {
+    var arg = args.join(' ').trim()
+    var path = resolveAbsPath(arg)
+    if (pathExists(path, true)) {
+      var content = getContents(path)
+      if (path.search('.md|.sh') != -1) {
+        content = hljs.highlightAuto(content).value
+      }
+      show('\n' + content + '\n\n')
+    } else {
+      show("cd: " + arg + ": no such file")
+    }
+  }
+  this.cd = function(args) {
+    var arg = args.join(' ').trim()
+    var path = resolveAbsPath(arg)
+    if (pathExists(path)) {
+      self.cwd = path
+      ev.trigger('prompt_set', getPrompt())
+    } else {
+      show("cd: " + arg + ": no such directory")
+    }
   }
   this.clear = function(args) {
     ev.trigger('disp_clear')
   }
-  this.version = function(args) {
-    show('Parsley Gardens Shell (pgsh) 1.0.0 Built with ' +
-         '<a target="_blank" href="http://riotjs.com/">Riot</a>')
-  }
-  this.git = function(args) {
-    show('Code Repository at <a target="_blank" ' +
-         'href="https://code.parsleygardens.net/explore/projects">' +
-    'code.parsleygardens.net</a>')
+  this.exit = function(args) {
+    if (self.su_active) {
+      self.su_active = false
+      ev.trigger('prompt_set', getPrompt())
+      return
+    }
+    show('Close browser window to exit')
   }
   this.hello = function(args) {
     address = args.join(' ').trim()
@@ -67,55 +141,40 @@ function pgsh(ev) {
       show('My name is not "' + address + '"')
     }
   }
-  this.magic = function(args) {
-    show('Animation and Illustration at <a target="_blank" ' +
-         'href="http://slightlymagic.com.au">slightlymagic.com.au</a>')
-  }
-  this.su = function(args) {
-    if (self.su_active !== true) {
-      self.su_active = true
-      if (!self.su_warned) {
-        self.su_warned = true
-        show('We trust you have received the usual lecture from the ' +
-             'local System Administrator.\n' +
-             'It usually boils down to these three things:\n\n' +
-             '    #1) Respect the privacy of others.\n' +
-             '    #2) Think before you type.\n' +
-             '    #3) With great power comes great\n\n')
+  this.help = function(args) {
+    command = args.join(' ').trim()
+    if (command in self.commands) {
+      show(self.commands[command])
+    } else if (command) {
+      show('No information for: ' + command)
+    } else {
+      var commands = [];
+      for (var name in self.commands) {
+        commands.push(name)
       }
-      ev.trigger('prompt_set', self.prompt_su)
+      show('Available commands:\n\n' + commands.sort().join(' ') +
+           '\n\n`help [command]` for more information.')
     }
   }
-  this.exit = function(args) {
-    if (self.su_active) {
-      self.su_active = false
-      ev.trigger('prompt_set', self.prompt)
-      return
+  this.ls = function(args) {
+    var arg = args.join(' ').trim()
+    var folder = arg || self.cwd
+    var path = resolveAbsPath(folder)
+    if (pathExists(path)) {
+      var contents = getContents(path)
+      var output = ''
+      for (var item in contents) {
+        output += item + "\n"
+      }
+      show(output)
+    } else {
+      show("ls: " + args + ": no such directory")
     }
-    show('Close browser window to exit')
   }
-  this.search = function(args) {
-    if (!args.join(' ').trim()) { return show(self.commands.search) }
-    ev.trigger('prompt_hide')
-    show('Searching for "' + args.join(' ') + '" in new window...')
-    setTimeout(function() {
-      window.open('https://duckduckgo.com/?q=' + args.join('+'), '_blank')
-      ev.trigger('prompt_show')
-    }, 1000)
+  this.pwd = function(args) {
+    show(self.cwd)
   }
-  this.questions = function(args) {
-    if (!self.active) {
-      self.active = 'questions'
-      ev.trigger('context_swap', 'questions')
-      set('Welcome to the questions. Do you want to continue?')
-      return
-    }
-    if (args == 'exit') {
-      self.active = ''
-      ev.trigger('context_swap')
-      show('Thanks for answering questions!')
-      return
-    }
+  this.question = function(args) {
     var questions = [
       'Isn\'t <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"' +
       ' target="_blank">this song</a> the best?',
@@ -125,28 +184,88 @@ function pgsh(ev) {
       "Don't you mean prism?",
       'Butts twelve by pies?',
       'I say there, Monstrosity. Do you know the times?',
-      '...is essay-writing an exercise in masking ignorance?',
       'What is the name of the spaces between the teeth of a comb?',
       'Why are you dressed up like Ship\'s Captain?'
     ]
-    set('You answered with "' + args + '"!\nNext question!\n' +
-      '<span style="color:#555">(Type "exit" to end)</span>\n\n')
     var rand = Math.floor(Math.random() * questions.length);
     show(questions[rand])
   }
-  this.help = function(args) {
-    command = args.join(' ').trim()
-    if (command in self.commands) {
-      show(self.commands[command])
-    } else if (command) {
-      show('No information for: ' + command)
-    } else {
-      var commands = [];
-      for(var name in self.commands) {
-        commands.push(name)
+  this.search = function(args) {
+    if (!args.join(' ').trim()) { return show(self.commands.search) }
+    ev.trigger('prompt_hide')
+    show('Searching for "' + args.join(' ') + '" in new window...')
+    setTimeout(function() {
+      window.open('https://duckduckgo.com/?q=' + args.join('+'), '_blank')
+      ev.trigger('prompt_show')
+    }, 1000)
+  }
+  this.su = function(args) {
+    if (self.su_active !== true) {
+      self.su_active = true
+      if (!self.su_warned) {
+        self.su_warned = true
+        show('We trust you have received the usual lecture from the ' +
+             'local System Administrator.\n' +
+             'It usually boils down to these three things:\n\n' +
+             '    #1) Respect the privacy of others.\n' +
+             '    #2) Think before you type.\n' +
+             '    #3) With great power comes great\n\n')
       }
-      show('Available commands:\n' + commands.sort().join(' ') +
-           '\n\n`help [command]` for more information.')
+      ev.trigger('prompt_set', getPrompt())
     }
   }
+  this.version = function(args) {
+    show('Parsley Gardens Shell (pgsh) 1.0.0\nBuilt with ' +
+         '<a target="_blank" href="http://riotjs.com/">Riot</a>')
+  }
+
+  /**
+   * Helper Functions
+   */
+  var show = function(text) { ev.trigger('disp_add', text) }
+  var set = function(text) { ev.trigger('disp_set', text) }
+
+  // Calculate a destination's path with respect to the current folder.
+  var resolveAbsPath = function(dest) {
+    var parts = dest.trim().split('/')
+    var absolute = dest.startsWith('/') || self.cwd == '/'
+    var path = absolute ? [''] : self.cwd.split('/')
+    parts.forEach(function(part) {
+      if (part == '..' && path.length > 1) { path.pop() }
+      if (part != '..' && part) { path.push(part) }
+    })
+    return path.length > 1 ? path.join('/') : '/'
+  }
+
+  // Check if a path exists in the tree
+  var pathExists = function(path, file = false) {
+    var parts = path.trim().split('/')
+    var fname = file ? parts.pop() : ''
+    var tree = self.tree
+    for (var i = 0; i < parts.length; i++) {
+      var part = parts[i]
+      if (!part) {
+        continue
+      }
+      if (!(tree.hasOwnProperty(part) && typeof tree[part] === 'object')) {
+        return false
+      }
+      tree = tree[part]
+    }
+    if (file && !(tree.hasOwnProperty(fname) && typeof tree[fname] === 'string')) {
+      return false
+    }
+    return true
+  }
+
+  // Return the contents of a given path.
+  var getContents = function(path) {
+    var parts = path.trim().split('/')
+    var tree = self.tree
+    parts.forEach(function(part) {
+      if (part) { tree = tree[part] }
+    })
+    return tree
+  }
+
 }

文件差异内容过多而无法显示
+ 1 - 0
js/vendor/highlight.pack.js


文件差异内容过多而无法显示
+ 0 - 1
js/vendor/riot+compiler.min.js


部分文件因为文件数量过多而无法显示