Merge branch 'andrewminer-tutorial-pages' into andrewminer-thermal-dynamics

This commit is contained in:
Andrew Miner
2015-03-20 19:21:25 -07:00
34 changed files with 759 additions and 97 deletions
Binary file not shown.
+7
View File
@@ -16,6 +16,7 @@ fs = require 'fs'
modSlugs = {}
itemSlugs = {}
tutorialSlugs = []
base = 'http://crafting-guide.com'
@@ -41,9 +42,15 @@ for modSlug, modData of DefaultMods
modVersion.eachItem (item)->
itemSlugs[item.slug] = item.slug
for tutorial in mod.tutorials
tutorialSlugs.push mod:mod.slug, tutorial:tutorial.slug
for modSlug in _.values(modSlugs).sort()
urls.push base + "/browse/#{modSlug}/"
for tutorialSlug in tutorialSlugs
urls.push base + "/browse/#{tutorialSlug.mod}/tutorials/#{tutorialSlug.tutorial}/"
for key in _.keys(itemSlugs).sort()
itemSlug = itemSlugs[key]
urls.push base + "/browse/#{itemSlug.mod}/#{itemSlug.item}/"
+3
View File
@@ -69,6 +69,9 @@ Url.mod = _.template "/browse/<%= modSlug %>/"
Url.modData = _.template "/data/<%= modSlug %>/mod.cg"
Url.modIcon = _.template "/browse/<%= modSlug %>/icon.png"
Url.modVersionData = _.template "/data/<%= modSlug %>/<%= modVersion %>/mod-version.cg"
Url.tutorial = _.template "/browse/<%= modSlug %>/tutorials/<%= tutorialSlug %>/"
Url.tutorialData = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>.cg"
Url.tutorialIcon = _.template "/browse/<%= modSlug %>/tutorials/<%= tutorialSlug %>/icon.png"
exports.UrlParam = UrlParam = {}
UrlParam.quantity = 'count'
@@ -0,0 +1,40 @@
###
Crafting Guide - markdown_section_controller.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
BaseController = require './base_controller'
########################################################################################################################
module.exports = class MarkdownSectionController extends BaseController
constructor: (options={})->
options.model ?= ''
options.title ?= 'Description'
options.templateName = 'markdown_section'
super options
@title = options.title
# BaseController Overrides #####################################################################
onDidRender: ->
@$title = @$('h2')
@$markdownPanel = @$('.markdown')
super
refresh: ->
@$title.html @title
@$markdownPanel.empty()
@$markdownPanel.html _.parseMarkdown @model
super
# Backbone.View Overrides ######################################################################
events: ->
return _.extend super,
'click .markdown': 'routeLinkClick'
@@ -11,6 +11,7 @@ ItemGroupController = require './item_group_controller'
Mod = require '../models/mod'
ModPack = require '../models/mod_pack'
PageController = require './page_controller'
TutorialController = require './tutorial_controller'
{Duration} = require '../constants'
{Text} = require '../constants'
{Url} = require '../constants'
@@ -55,15 +56,17 @@ module.exports = class ModPageController extends PageController
onDidRender: ->
@adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper'
@$name = @$('.name')
@$byline = @$('.byline p')
@$description = @$('.description p')
@$documentationLink = @$('.documentation')
@$downloadLink = @$('.download')
@$homePageLink = @$('.homePage')
@$groupContainer = @$('.itemGroups')
@$titleImage = @$('.titleImage img')
@$versionSelector = @$('select.version')
@$name = @$('.name')
@$byline = @$('.byline p')
@$description = @$('.description p')
@$documentationLink = @$('.documentation')
@$downloadLink = @$('.download')
@$homePageLink = @$('.homePage')
@$groupContainer = @$('.itemGroups')
@$titleImage = @$('.titleImage img')
@$tutorialsSection = @$('.tutorials')
@$tutorialsContainer = @$('.tutorials .panel')
@$versionSelector = @$('select.version')
super
@@ -83,6 +86,7 @@ module.exports = class ModPageController extends PageController
@_refreshLink @$downloadLink, @model.downloadUrl
@_refreshItemGroups()
@_refreshTutorials()
@_refreshVersions()
super
@@ -128,7 +132,7 @@ module.exports = class ModPageController extends PageController
while @_groupControllers.length > groupIndex + 1
controller = @_groupControllers.pop()
controller.$el.slideUp duration:Duration.normal, -> @remove()
controller.$el.slideUp duration:Duration.normal, complete:-> @remove()
_refreshLink: ($link, url)->
if url?
@@ -137,6 +141,32 @@ module.exports = class ModPageController extends PageController
else
$link.slideUp duration:Duration.normal
_refreshTutorials: ->
@_tutorialControllers ?= []
tutorials = @model.tutorials
if tutorials.length is 0
@$tutorialsSection.addClass 'hidden'
else
@$tutorialsSection.removeClass 'hidden'
index = 0
for tutorial in tutorials
controller = @_tutorialControllers[index]
if not controller?
controller = new TutorialController model:tutorial
controller.render()
@$tutorialsContainer.append controller.$el
@_tutorialControllers.push controller
else
controller.model = model
index += 1
while @_tutorialControllers.length > index
controller = @_tutorialControllers.pop()
controller.$el.slideUp duration:Duration.normal, complete:-> @remove()
_refreshVersions: ->
@$versionSelector.empty()
return unless @model?
@@ -0,0 +1,39 @@
###
Crafting Guide - tutorial_controller.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
BaseController = require './base_controller'
{Url} = require '../constants'
########################################################################################################################
module.exports = class TutorialController extends BaseController
constructor: (options={})->
if not options.model? then throw new Error 'options.model is required'
options.templateName = 'tutorial'
super options
# BaseController Overrides #####################################################################
onDidRender: ->
@$icon = @$('img')
@$link = @$('a')
@$title = @$('p')
super
refresh: ->
templateData = modSlug:@model.modSlug, tutorialSlug:@model.slug
@$icon.attr 'src', Url.tutorialIcon templateData
@$link.attr 'href', Url.tutorial templateData
@$title.html @model.name
super
# Backbone.View Overrides ######################################################################
events: ->
return _.extend super,
'click a': 'routeLinkClick'
@@ -0,0 +1,159 @@
###
Crafting Guide - tutorial_page_controller.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
AdsenseController = require './adsense_controller'
BaseController = require './base_controller'
MarkdownSectionController = require './markdown_section_controller'
VideoController = require './video_controller'
{Duration} = require '../constants'
{Event} = require '../constants'
{Url} = require '../constants'
########################################################################################################################
module.exports = class TutorialPageController extends BaseController
constructor: (options={})->
if not options.modSlug? then throw new Error 'options.modSlug is required'
if not options.tutorialSlug? then throw new Error 'options.tutorialSlug is required'
if not options.modPack? then throw new Error 'options.modPack is required'
options.model ?= null
options.templateName = 'tutorial_page'
super options
@modPack = options.modPack
@imageLoader = options.imageLoader
@modSlug = options.modSlug
@tutorialSlug = options.tutorialSlug
@modPack.on Event.change, => @_resolveTutorial()
@_resolveTutorial()
# BaseController Overrides #####################################################################
onDidRender: ->
@adsenseController = @addChild AdsenseController, '.view__adsense', model:'sidebar_skyscraper'
@$byline = @$('.byline')
@$bylineLink = @$('.byline a')
@$name = @$('.name')
@$officialLink = @$('a.officialPage')
@$sectionsContainer = @$('.sections')
@$title = @$('h1.name')
@$titleImage = @$('.titleImage img')
@$videosSection = @$('.videos')
@$videosSectionTitle = @$('.videos h2')
@$videosSectionPanel = @$('.videos .panel')
super
refresh: ->
if @model? and @model.isLoaded
@$el.removeClass 'hidden'
else
@$el.addClass 'hidden'
@_refreshByline()
@_refreshOfficialUrl()
@_refreshSections()
@_refreshTitle()
@_refreshVideos()
super
# Private Methods ##############################################################################
_refreshByline: ->
if @model?
@$byline.removeClass 'hidden'
@$bylineLink.html @modPack.getMod(@modSlug).name
@$bylineLink.attr 'href', Url.mod modSlug:@modSlug
else
@$byline.addClass 'hidden'
_refreshOfficialUrl: ->
if @model?.officialUrl?
@$officialLink.attr 'href', @model.officialUrl
@$officialLink.removeClass 'hidden'
else
@$officialLink.addClass 'hidden'
_refreshTitle: ->
if @model?
@$title.html @model.name
@$titleImage.attr 'src', Url.tutorialIcon modSlug:@modSlug, tutorialSlug:@tutorialSlug
else
@$title.empty()
@$titleImage.removeAttr 'src'
_refreshSections: ->
@_sectionControllers ?= []
index = 0
if @model?
for section in @model.sections
controller = @_sectionControllers[index]
if not controller?
controller = new MarkdownSectionController title:section.title, model:section.content
controller.render()
@$sectionsContainer.append controller.$el
@_sectionControllers.push controller
else
controller.title = section.title
controller.model = section.model
controller.refresh()
index += 1
while @_sectionControllers.length > index
controller = @_sectionController.pop()
controller.$el.fadeOut duration:Duration.normal, complete:-> @remove()
_refreshVideos: ->
@_videoControllers ?= []
index = 0
videos = @model?.videos or []
if videos? and videos.length > 0
@$videosSection.slideDown duration:Duration.normal
@$videosSectionTitle.html if videos.length is 1 then 'Video' else 'Videos'
for video in videos
controller = @_videoControllers[index]
if not controller?
controller = new VideoController model:video
@_videoControllers.push controller
controller.render()
@$videosSectionPanel.append controller.$el
else
controller.model = video
index++
else
@$videosSection.slideUp duration:Duration.normal
while @_videoControllers.length > index
controller = @_videoControllers.pop()
controller.$el.slideUp duration:Duration.normal, complete:-> controller.$el.remove()
_resolveTutorial: ->
return if @model?
mod = @modPack.getMod @modSlug
if not mod?
logger.error => "cannot find the mod for: #{@modSlug}"
router.navigate '/', trigger:true
return
if not mod.isLoaded
mod.fetch()
return
@model = mod.getTutorial @tutorialSlug
if not @model?
logger.error => "mod #{@modSlug} doesn't have a tutorial for: #{@tutorialSlug}"
return
@model.fetch()
+13 -7
View File
@@ -16,6 +16,7 @@ ItemSlug = require './models/item_slug'
Mod = require './models/mod'
ModPack = require './models/mod_pack'
ModPageController = require './controllers/mod_page_controller'
TutorialPageController = require './controllers/tutorial_page_controller'
Storage = require './models/storage'
UrlParams = require './url_params'
{ProductionEnvs} = require './constants'
@@ -64,13 +65,14 @@ module.exports = class CraftingGuideRouter extends Backbone.Router
@_recordPageView()
routes:
'(/)': 'route__home'
'browse(/)': 'route__browse'
'browse/:modSlug(/)': 'route__browseMod'
'browse/:modSlug/:itemSlug(/)': 'route__browseModItem'
'configure(/)': 'route__configure'
'craft(/)': 'route__craft'
'craft/:text': 'route__craft'
'(/)': 'route__home'
'browse(/)': 'route__browse'
'browse/:modSlug(/)': 'route__browseMod'
'browse/:modSlug/:itemSlug(/)': 'route__browseModItem'
'browse/:modSlug/tutorials/:tutorialSlug(/)': 'route__browseTutorial'
'configure(/)': 'route__configure'
'craft(/)': 'route__craft'
'craft/:text': 'route__craft'
'item/:itemSlug': 'deprecated__item'
'crafting/(:text)': 'deprecated__crafting'
@@ -100,6 +102,10 @@ module.exports = class CraftingGuideRouter extends Backbone.Router
controller = new ItemPageController _.extend {itemSlug:slug}, @_defaultOptions
@_setPage 'browseModItem', controller
route__browseTutorial: (modSlug, tutorialSlug)->
controller = new TutorialPageController _.extend {modSlug:modSlug, tutorialSlug:tutorialSlug}, @_defaultOptions
@_setPage 'browseTutorial', controller
route__configure: ->
@_setPage 'configure', new ConfigurePageController _.extend {}, @_defaultOptions
+1 -1
View File
@@ -22,7 +22,7 @@ module.exports = class ItemPage extends BaseModel
compileDescription: ->
return null unless @item?.description?
description = markdown.parse @item.description, 'Maruku'
description = _.parseMarkdown @item.description
return description
findComponentInItems: ->
+41 -21
View File
@@ -16,6 +16,7 @@ module.exports = class Mod extends BaseModel
constructor: (attributes={}, options={})->
if not attributes.slug? then throw new Error 'attributes.slug is required'
attributes.author ?= ''
attributes.description ?= ''
attributes.documentationUrl ?= null
@@ -23,11 +24,13 @@ module.exports = class Mod extends BaseModel
attributes.homePageUrl ?= null
attributes.modPack ?= null
attributes.name ?= ''
super attributes, options
@_activeModVersion = null
@_activeVersion = null
@_modVersions = []
@_tutorials = []
Object.defineProperties this,
'activeModVersion': { get:-> @_activeModVersion }
@@ -107,6 +110,31 @@ module.exports = class Mod extends BaseModel
# Property Methods #############################################################################
getActiveVersion: ->
return @_activeVersion
setActiveVersion: (version)->
return if version is @_activeVersion
version ?= Mod.Version.None
if version is Mod.Version.Latest then version = _.last(@_modVersions).version
if version is Mod.Version.None
@_activeVersion = version
@_activateModVersion null
@trigger Event.change + ':activeVersion', this, @_activeVersion
@trigger Event.change, this
else
for modVersion in @_modVersions
if version is modVersion.version
@_activateModVersion modVersion
break
@_activeVersion = version
@trigger Event.change + ':activeVersion', this, @_activeVersion
@trigger Event.change, this
addModVersion: (modVersion)->
return unless modVersion?
return if @_modVersions.indexOf(modVersion) isnt -1
@@ -136,30 +164,22 @@ module.exports = class Mod extends BaseModel
return null
getActiveVersion: ->
return @_activeVersion
addTutorial: (tutorial)->
return unless tutorial?
if @getTutorial(tutorial.slug)? then throw new Error "duplicate tutorial: #{tutorial.name}"
@_tutorials.push tutorial
tutorial.modSlug = @slug
setActiveVersion: (version)->
return if version is @_activeVersion
getAllTutorials: ->
return @_tutorials[..]
version ?= Mod.Version.None
if version is Mod.Version.Latest then version = _.last(@_modVersions).version
getTutorial: (tutorialSlug)->
for tutorial in @_tutorials
return tutorial if tutorial.slug is tutorialSlug
return null
if version is Mod.Version.None
@_activeVersion = version
@_activateModVersion null
@trigger Event.change + ':activeVersion', this, @_activeVersion
@trigger Event.change, this
else
for modVersion in @_modVersions
if version is modVersion.version
@_activateModVersion modVersion
break
@_activeVersion = version
@trigger Event.change + ':activeVersion', this, @_activeVersion
@trigger Event.change, this
Object.defineProperties @prototype,
tutorials: { get:@prototype.getAllTutorials }
# Backbone.View Overrides ######################################################################
@@ -125,6 +125,7 @@ module.exports = class CommandParserVersionBase
shortestIndent = Number.MAX_VALUE
for hereDocLine in hereDocLines
continue if hereDocLine.trim().length is 0
shortestIndent = Math.min hereDocLine.match(/( *).*/)[1].length, shortestIndent
for i in [0...hereDocLines.length]
@@ -8,6 +8,7 @@ All rights reserved.
CommandParserVersionBase = require './command_parser_version_base'
Mod = require '../mod'
ModVersion = require '../mod_version'
Tutorial = require '../tutorial'
########################################################################################################################
@@ -47,17 +48,23 @@ module.exports = class ModParserV1 extends CommandParserVersionBase
if downloadUrl.length is 0 then throw new Error 'downloadUrl cannot be empty (omit it instead)'
@_rawData.downloadUrl = downloadUrl
_command_name: (name)->
if @_rawData.name? then throw new Error 'duplicate declaration of "name"'
if name.length is 0 then throw new Error '"name" cannot be empty'
@_rawData.name = name
_command_homePageUrl: (homePageUrl='')->
if @_rawData.homePageUrl? then throw new Error 'duplicate declaration of "homePageUrl"'
if homePageUrl.length is 0 then throw new Error 'homePageUrl cannot be empty'
@_rawData.homePageUrl = homePageUrl
_command_name: (name)->
if @_rawData.name? then throw new Error 'duplicate declaration of "name"'
if name.length is 0 then throw new Error '"name" cannot be empty'
@_rawData.name = name
_command_tutorial: (nameParts...)->
name = nameParts.join(', ').trim()
if name.length is 0 then throw new Error '"name" cannot be empty'
@_rawData.tutorialNames ?= []
@_rawData.tutorialNames.push name
_command_version: (version='')->
if version.length is 0 then throw new Error 'version cannot be empty'
@@ -78,5 +85,9 @@ module.exports = class ModParserV1 extends CommandParserVersionBase
model.name = rawData.name
model.homePageUrl = rawData.homePageUrl
if rawData.tutorialNames?
for tutorialName in rawData.tutorialNames
model.addTutorial new Tutorial name:tutorialName
for version in rawData.versions
model.addModVersion new ModVersion modSlug:model.slug, version:version
@@ -0,0 +1,65 @@
###
Crafting Guide - tutorial_parser_v1.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
CommandParserVersionBase = require './command_parser_version_base'
Tutorial = require '../tutorial'
########################################################################################################################
module.exports = class TutorialParserV1 extends CommandParserVersionBase
# CommandParserVersionBase Overrides ###########################################################
_buildModel: (rawData, model)->
@_buildTutorial rawData, model
_unparseModel: (builder, model)->
@_unparseTutorial builder, model
# Command Methods ##############################################################################
_command_content: (contentParts...)->
if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"'
if @_rawData.currentSection.content? then throw new Error 'duplicate declaration of content'
content = contentParts.join(', ').trim()
if not content.length > 0 then throw new Error 'content cannot be empty'
@_rawData.currentSection.content = content
_command_officialUrl: (officialUrl)->
if @_rawData.officialUrl? then throw new Error 'duplicate declaration of "officialUrl"'
if officialUrl.length is 0 then throw new Error 'officialUrl cannot be empty'
@_rawData.officialUrl = officialUrl
_command_section: (textParts...)->
@_rawData.sections ?= []
@_rawData.sections.push @_rawData.currentSection = {}
_command_title: (titleParts...)->
if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"'
if @_rawData.currentSection.title? then throw new Error 'duplicate declaration of title'
title = titleParts.join(', ').trim()
if not title.length > 0 then throw new Error 'title cannot be empty'
@_rawData.currentSection.title = title
_command_video: (youTubeId, nameParts...)->
if not youTubeId?.length then throw new Error 'video declaration requires a YouTubeID'
name = nameParts.join ', '
if not name?.length then throw new Error 'video declaration requires a name'
@_rawData.videos ?= []
@_rawData.videos.push youTubeId:youTubeId, name:name
# Object Building Methods ######################################################################
_buildTutorial: (rawData, model)->
if not rawData.sections? then throw new Error 'the "section" declaration is required'
model.officialUrl = rawData.officialUrl
model.videos = rawData.videos
model.sections = rawData.sections
+35
View File
@@ -0,0 +1,35 @@
###
Crafting Guide - tutorial.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
BaseModel = require './base_model'
TutorialParser = require './tutorial_parser'
{Url} = require '../constants'
########################################################################################################################
module.exports = class Tutorial extends BaseModel
constructor: (attributes={}, options={})->
if not attributes.name?.length > 0 then throw new Error "attributes.name cannot be empty"
attributes.modSlug ?= null
attributes.officialUrl ?= null
attributes.sections ?= []
attributes.slug ?= _.slugify attributes.name
attributes.videos ?= []
super attributes, options
# Backbone.Model Overrides #####################################################################
parse: (text)->
TutorialParser = require './tutorial_parser' # to avoid require cycles
@_parser ?= new TutorialParser model:this
@_parser.parse text
return null # prevent calling `set`
url: ->
return Url.tutorialData modSlug:@modSlug, tutorialSlug:@slug
+19
View File
@@ -0,0 +1,19 @@
###
Crafting Guide - tutorial_parser.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
###
VersionedParserBase = require './versioned_parser_base'
TutorialParserV1 = require './parser_versions/tutorial_parser_v1'
########################################################################################################################
module.exports = class TutorialParser extends VersionedParserBase
# VersionedParserBase Overrides ################################################################
_createParsers: (options)->
return result =
'1': new TutorialParserV1 options
@@ -40,9 +40,9 @@ describe 'command_parser_version_base.coffee', ->
expect(result[1]).to.be.null
it 'trims smallest leading whitespace', ->
parser._lines = ['command: <<-END', ' alpha', ' bravo', ' charlie', 'END', 'command1: arg2']
parser._lines = ['command: <<-END', ' alpha', ' bravo', '', ' charlie', 'END', 'command1: arg2']
parser._lineNumber = 1
result = parser._parseHereDoc parser._lines[0]
result[0].should.equal 'command: '
result[1].should.equal 'alpha\n bravo\ncharlie'
result[1].should.equal 'alpha\n bravo\n\ncharlie'
+5 -2
View File
@@ -1,5 +1,5 @@
###
Crafting Guide - underscore.coffee
Crafting Guide - underscore_mixins.coffee
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
@@ -7,12 +7,15 @@ All rights reserved.
_.mixin
parseMarkdown: (text)->
return markdown.parse text, 'Maruku'
slugify: (text)->
return null unless text?
result = text.toLowerCase()
result = result.replace /[^a-zA-Z0-9_]/g, '_'
result = result.replace /__+/, '_'
result = result.replace /__+/g, '_'
result = result.replace /^_/, ''
result = result.replace /_$/, ''
return result
+10
View File
@@ -0,0 +1,10 @@
//-
//- Crafting Guide - markdown_section.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__markdown_section.section
h2
.panel.markdown
+4
View File
@@ -20,4 +20,8 @@
.byline: p
.description: p
.tutorials.section
h2 Tutorials
.panel
.itemGroups
+11
View File
@@ -0,0 +1,11 @@
//-
//- Crafting Guide - tutorial.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__tutorial
a
img
.caption: p
+23
View File
@@ -0,0 +1,23 @@
//-
//- Crafting Guide - tutorial_page.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__tutorial_page
.sidebar
.titleImage: a: img
a.officialPage.externalLink(target="new"): p Offical Documentation
.view__adsense
.mainBody
h1.name
.byline: p from <a></a>
.sections
.videos.section
h2
.panel
+32 -9
View File
@@ -5,6 +5,16 @@ Copyright (C) 2015 by Redwood Labs
All rights reserved.
*/
.byline {
margin: 0.25em 0 2em 0;
p {
font-family: $font-family-normal;
font-size: $font-size-normal;
font-style: italic;
}
}
.centered {
text-align: center;
}
@@ -22,6 +32,20 @@ All rights reserved.
.error-new { background: $color-error-new !important; }
.hidden {
max-height: 0;
opacity: 0;
}
.mainBody {
position: relative; width: 81.25%;
display: inline-block;
padding: 1em;
padding-top: 2em;
vertical-align: top;
}
.sidebar {
position: relative; width: 18.75%;
@@ -53,15 +77,6 @@ All rights reserved.
}
}
.mainBody {
position: relative; width: 81.25%;
display: inline-block;
padding: 1em;
padding-top: 2em;
vertical-align: top;
}
.section {
margin-top: 3em;
@@ -86,4 +101,12 @@ All rights reserved.
background: white;
padding: 1em;
}
}
.videos {
display: none;
.panel {
text-align: center;
}
}
+13
View File
@@ -39,6 +39,19 @@ All rights reserved.
}
}
ol {
margin: 2em 2em 0 2em;
li {
font-family: $font-family-normal;
font-size: $font-size-normal;
line-height: $font-size-normal + 0.15em;
list-style: decimal;
margin: 0.66em 0 0 2em;
}
}
ul {
margin: 2em 2em 0 2em;
+6
View File
@@ -48,6 +48,12 @@ h1 {
font-family: $font-family-header;
font-size: $font-size-xx-large;
}
&.name {
font-family: $font-family-header;
font-size: $font-size-x-large;
margin: 0;
}
}
h2 {
+1
View File
@@ -23,4 +23,5 @@ All rights reserved.
@import 'mod_page';
@import 'mod_selector';
@import 'stack';
@import 'tutorial';
@import 'video';
-24
View File
@@ -24,22 +24,6 @@ All rights reserved.
}
.mainBody {
h1.name {
font-family: $font-family-header;
font-size: $font-size-x-large;
margin: 0;
}
.byline {
display: none;
margin: 0.25em 0 2em 0;
p {
font-family: $font-family-normal;
font-size: $font-size-normal;
font-style: italic;
}
}
.recipes {
display: none;
@@ -61,14 +45,6 @@ All rights reserved.
.usedToMake {
display: none;
}
.videos {
display: none;
.panel {
text-align: center;
}
}
}
.view__item {
-16
View File
@@ -23,22 +23,6 @@ All rights reserved.
.mainBody {
.name {
font-family: $font-family-header;
font-size: $font-size-x-large;
margin: 0;
}
.byline {
margin: 0.25em 0 2em 0;
p {
font-family: $font-family-normal;
font-size: $font-size-normal;
font-style: italic;
}
}
.description {
margin-bottom: 4em;
+28
View File
@@ -0,0 +1,28 @@
/*
Crafting Guide - tutorial.scss
Copyright (C) 2015 by Redwood Labs
All rights reserved.
*/
.view__tutorial {
position: relative;
display: inline-block;
margin-left: 1em;
vertical-align: top;
&:first-child {
margin-left: 0;
}
.caption {
position: relative; width: 100%;
display: block;
p {
margin-top: 0.5em;
font-weight: bold;
text-align: center;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 378 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

@@ -0,0 +1,107 @@
<!DOCTYPE html><html><head>
<title>The Ultimate Minecraft Crafting Guide</title>
<meta charset="UTF-8">
<link href="/images/favicon.png" rel="icon" type="image/png">
<link rel="stylesheet" type="text/css" href="/css/main.css">
<link rel="stylesheet" type="text/css" href="/css/jquery-ui.css">
</head>
<body>
<div class="view__feedback" style="left: -250px; "><input name="name" placeholder="name (optional)"><input name="email" placeholder="email (optional)"><label name="comment">Comment:</label><textarea name="comment"></textarea><button name="send" disabled="disabled">send</button><div class="error"><p>Sending failed. Please try again later.</p></div><div class="label"><img src="/images/paper.png"><p>Feedback</p></div></div>
<div class="view__screen"></div>
<div class="content">
<div class="view__header">
<h1><a href="/" class="logo"><img src="/images/workbench_front.png"></a>
<p>Crafting Guide for Minecraft</p>
</h1>
<div class="addthis_sharing_toolbox"></div>
<div class="divider bottom"></div>
<div class="navBar"><a data-page="home" href="/" style="z-index: 104; ">
<p>Home</p>
<div class="dot" style="opacity: 0; "></div></a><a data-page="configure" href="/configure/" style="z-index: 103; ">
<p>Configure</p>
<div class="dot" style="opacity: 0; "></div></a><a data-page="browse" href="/browse/" style="z-index: 102; ">
<p>Browse</p>
<div class="dot" style="opacity: 1; "></div></a><a data-page="craft" href="/craft/" style="z-index: 101; ">
<p>Craft</p>
<div class="dot" style="opacity: 0; "></div></a></div>
</div>
<div class="view__tutorial_page page" style=""><div class="sidebar"><div class="titleImage"><a><img src="/browse/buildcraft/tutorials/gates_wires_and_chips/icon.png"></a></div><a target="new" class="officialPage externalLink hidden"><p>Offical Documentation</p></a><div class="view__adsense placeholder sidebar_skyscraper"></div></div><div class="mainBody"><h1 class="name">Gates, Wires, and Chips</h1><div class="byline"><p>from <a href="/browse/buildcraft/">Buildcraft</a></p></div><div class="sections"><div class="view__markdown_section section"><h2>What do gates do?</h2><div class="panel markdown"><p>BuildCraft gates are devices which can be attached to a pipe to detect and interact with objects nearby. Gates
can read a wide variety of conditions: that a nearby chest is full, or that a <a href="/browse/buildcraft/combustion_engine">Combustion
Engine</a> is about to overheat. In reaction to these conditions, gates can
emit various kinds of signals (including redstone signals) to control other gates and/or machines.</p></div></div><div class="view__markdown_section section"><h2>An Example: Controlling Engines</h2><div class="panel markdown"><p>Before diving into all the details, let's look at a realistic example of what you might do with gates. This is a
small power plant driving a quarry.</p>
<p><img alt="" src="./example_1_overview.png"></p>
<p>Here are the important pieces of the build:</p>
<ol><li>The on/off switch for the entire operation. Flipping the switch creates a redstone signal.</li><li>A <a href="/browse/buildcraft/basic_gate/">Basic Gate</a> attached to a <a href="/browse/buildcraft/structure_pipe">Structure Pipe</a> reads the redstone signal and generates a red pipe wire signal.</li><li><a href="/browse/buildcraft/red_pipe_wire">Red Pipe Wire</a> follows the <a href="/browse/buildcraft/cobblestone_kinesis_pipe">Cobblestone Kinesis Pipe</a>, transmitting the signal throughout the rest of the build.</li><li>Another Basic Gate receives the red pipe wire signal and converts it back to a redstone signal, thus turning
the <a href="/browse/buildcraft/combustion_engine">Combustion Engine</a>s on.</li><li>The red pipe wire signal is also received by Basic Gates next to the <a href="/browse/buildcraft/redstone_engine">Redstone
Engine</a>s, turning them on as well, and causing both fuel and water to
flow into the engines.</li><li>Finally, the power generated by the Combusion Engines flows into the <a href="/browse/buildcraft/quarry/">Quarry</a>.</li></ol></div></div></div><div class="videos section" style="display: block; "><h2>Video</h2><div class="panel"><div class="view__video"><iframe width="365" height="273" src="http://www.youtube.com/embed/J6-VUApZGQs?modestbranding=1&amp;autohide=1&amp;showinfo=0" frameborder="0" allowfullscreen="true"></iframe><div class="caption"><p>Buildcraft Gates Tutorial, Part 1</p></div></div></div></div></div></div>
<div class="view__footer">
<div class="divider top"></div>
<div class="left">
<h2>
<p>About</p>
</h2>
<p>
Crafting Guide gives step-by-step tutorials for making anything in Minecraft or its many mods. Just say what
you'd like to make, what you already have, it will do the rest, giving you a list of raw materials you need
to collect and step-by-step instructions of how much to make of which items in the proper order. You can
even ask it to include the materials and instructions for all the tools you'll need along the way!
</p>
</div>
<div class="center">
<h2>
<p>Donate</p>
</h2>
<p>Crafting Guide is free for all, but if you find it helpful, donations in any amount are gratefully accepted.</p>
<div class="action">
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" class="centered">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="GCB2TYZJYLAE6">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"><img src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</div>
</div>
<div class="right">
<h2>
<p>Get Involved</p>
</h2>
<p>
Crafting Guide is completely open-source, and you can help! Whether you want to write a recipe book (all
simple JSON), or implement new features, just head over to GitHub to get started.
</p>
<div class="action">
<iframe src="http://ghbtns.com/github-btn.html?user=andrewminer&amp;repo=crafting-guide&amp;type=fork&amp;size=large" allowtransparency="true" frameborder="0" scrolling="0" width="100" height="32"></iframe>
</div>
</div><a href="/test.html" rel="nofollow">
<div class="divider bottom"></div></a>
</div>
</div>
<script src="/js/underscore.js"></script>
<script src="/js/jquery.js"></script>
<script src="/js/backbone.js"></script>
<script src="/js/jade.js"></script>
<script src="/js/markdown.js"></script>
<script src="/js/when.js"></script>
<script src="/js/jquery-ui.js"></script>
<script src="/js/main.js"></script>
<script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
if (window.location.hostname === 'crafting-guide.com') {
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-54970416-2', 'crafting-guide.com');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
}
</script>
</body></html>
+2
View File
@@ -8,3 +8,5 @@ documentationUrl: http://www.mod-buildcraft.com/wiki/doku.php
downloadUrl: http://www.mod-buildcraft.com/download/
version: 6.2.6
tutorial: Gates, Wires, and Chips
@@ -0,0 +1,35 @@
schema: 1
section:
title: What do gates do?
content: <<-END
BuildCraft gates are devices which can be attached to a pipe to detect and interact with objects nearby. Gates
can read a wide variety of conditions: that a nearby chest is full, or that a [Combustion
Engine](/browse/buildcraft/combustion_engine) is about to overheat. In reaction to these conditions, gates can
emit various kinds of signals (including redstone signals) to control other gates and/or machines.
END
section:
title: An Example: Controlling Engines
content: <<-END
Before diving into all the details, let's look at a realistic example of what you might do with gates. This is a
small power plant driving a quarry.
![](./example_1_overview.png)
Here are the important pieces of the build:
1. The on/off switch for the entire operation. Flipping the switch creates a redstone signal.
2. A [Basic Gate](/browse/buildcraft/basic_gate/) attached to a [Structure Pipe]
(/browse/buildcraft/structure_pipe) reads the redstone signal and generates a red pipe wire signal.
3. [Red Pipe Wire](/browse/buildcraft/red_pipe_wire) follows the [Cobblestone Kinesis Pipe]
(/browse/buildcraft/cobblestone_kinesis_pipe), transmitting the signal throughout the rest of the build.
4. Another Basic Gate receives the red pipe wire signal and converts it back to a redstone signal, thus turning
the [Combustion Engine](/browse/buildcraft/combustion_engine)s on.
5. The red pipe wire signal is also received by Basic Gates next to the [Redstone
Engine](/browse/buildcraft/redstone_engine)s, turning them on as well, and causing both fuel and water to
flow into the engines.
6. Finally, the power generated by the Combusion Engines flows into the [Quarry](/browse/buildcraft/quarry/).
END
video: J6-VUApZGQs, Buildcraft Gates Tutorial, Part 1
+1
View File
@@ -13,6 +13,7 @@ http://crafting-guide.com/browse/minecraft/
http://crafting-guide.com/browse/railcraft/
http://crafting-guide.com/browse/thermal_dynamics/
http://crafting-guide.com/browse/thermal_expansion/
http://crafting-guide.com/browse/buildcraft/tutorials/gates_wires_and_chips/
http://crafting-guide.com/browse/applied_energistics_2/128_spatial_component/
http://crafting-guide.com/browse/applied_energistics_2/128_spatial_storage_cell/
http://crafting-guide.com/browse/applied_energistics_2/16_spatial_component/