Show markdown description text on item detail page
* Update build process to *not* copy over prerendered pages during a regular build (only during a `dist` build) * Add dependency on npm "markdown" package and include it in the scripts loaded in the default layout * Update the Item model to be able to load from a *.cg file * Add an ItemParser to process the `item.cg` file * Update the general parser to be able to work with HereDoc-style text blocks * Add a markdown-specific stylesheet * Add a sample of the `item.cg` file format (Advanced Crafting Table)
This commit is contained in:
+19
-3
@@ -22,6 +22,7 @@ module.exports = (grunt)->
|
||||
extensions: ['.coffee']
|
||||
files:
|
||||
'./dist/js/main.js': ['./src/coffee/main.coffee']
|
||||
|
||||
test:
|
||||
options:
|
||||
transform: ['coffeeify']
|
||||
@@ -30,6 +31,15 @@ module.exports = (grunt)->
|
||||
extensions: ['.coffee']
|
||||
files:
|
||||
'./dist/js/test.js': ['./src/coffee/test/test.coffee']
|
||||
|
||||
markdown:
|
||||
options:
|
||||
browserifyOptions:
|
||||
debug: false
|
||||
standalone: 'markdown'
|
||||
files:
|
||||
'./dist/js/markdown.js': ['./node_modules/markdown/lib/index.js']
|
||||
|
||||
when:
|
||||
options:
|
||||
browserifyOptions:
|
||||
@@ -102,6 +112,12 @@ module.exports = (grunt)->
|
||||
src: './static/'
|
||||
dest: './dist/'
|
||||
recursive: true
|
||||
non_html:
|
||||
options:
|
||||
src: './static/'
|
||||
dest: './dist/'
|
||||
exclude: '*.html'
|
||||
recursive: true
|
||||
|
||||
sass:
|
||||
build:
|
||||
@@ -134,7 +150,7 @@ module.exports = (grunt)->
|
||||
tasks: ['browserify:main']
|
||||
jade:
|
||||
files: ['./src/**/*.jade']
|
||||
tasks: ['jade:pages', 'jade:templates']
|
||||
tasks: ['jade:pages', 'jade:templates', 'browserify:main']
|
||||
sass:
|
||||
files: ['./src/**/*.scss']
|
||||
tasks: ['sass', 'copy:styles']
|
||||
@@ -144,8 +160,8 @@ module.exports = (grunt)->
|
||||
|
||||
grunt.registerTask 'default', 'build'
|
||||
|
||||
grunt.registerTask 'build', [ 'rsync', 'copy', 'sass:build', 'jade', 'browserify', 'exorcise' ]
|
||||
grunt.registerTask 'build', [ 'rsync:non_html', 'copy', 'sass:build', 'jade', 'browserify', 'exorcise' ]
|
||||
|
||||
grunt.registerTask 'dist', ['clean', 'build', 'copy:index_prerender', 'sass:dist', 'uglify']
|
||||
grunt.registerTask 'dist', ['clean', 'build', 'rsync:static', 'copy:index_prerender', 'sass:dist', 'uglify']
|
||||
|
||||
grunt.registerTask 'clean-watch', ['clean', 'build', 'watch']
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"chai": "^1.10.0",
|
||||
"jade": "^1.8.2",
|
||||
"jquery": "^2.1.3",
|
||||
"markdown": "^0.5.0",
|
||||
"mocha": "^2.0.1",
|
||||
"sinon": "^1.12.2",
|
||||
"sinon-chai": "^2.6.0",
|
||||
|
||||
@@ -56,14 +56,15 @@ ModelState.failed = 'failed'
|
||||
exports.Text = Text = {}
|
||||
Text.title = 'Crafting Guide for Minecraft | The Ultimate Step-by-Step Tutorial for Making Anything in Minecraft'
|
||||
|
||||
exports.Url = Url = {}
|
||||
Url.crafting = _.template "/craft/<%= inventoryText %>"
|
||||
Url.itemIcon = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/icon.png"
|
||||
Url.item = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/"
|
||||
Url.mod = _.template "/browse/<%= modSlug %>/"
|
||||
Url.modData = _.template "/data/<%= modSlug %>/mod.cg"
|
||||
Url.modIcon = _.template "/browse/<%= modSlug %>/icon.png"
|
||||
Url.modVersion = _.template "/data/<%= modSlug %>/<%= modVersion %>/mod-version.cg"
|
||||
exports.Url = Url = {}
|
||||
Url.crafting = _.template "/craft/<%= inventoryText %>"
|
||||
Url.item = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/"
|
||||
Url.itemData = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/item.cg"
|
||||
Url.itemIcon = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/icon.png"
|
||||
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"
|
||||
|
||||
exports.UrlParam = UrlParam = {}
|
||||
UrlParam.quantity = 'count'
|
||||
|
||||
@@ -18,8 +18,8 @@ module.exports = class ItemController extends BaseController
|
||||
options.templateName = 'item'
|
||||
super options
|
||||
|
||||
@_imageLoader = options.imageLoader
|
||||
@_modPack = options.modPack
|
||||
@imageLoader = options.imageLoader
|
||||
@modPack = options.modPack
|
||||
|
||||
# BaseController Overrides #####################################################################
|
||||
|
||||
@@ -30,9 +30,9 @@ module.exports = class ItemController extends BaseController
|
||||
super
|
||||
|
||||
refresh: ->
|
||||
display = @_modPack.findItemDisplay @model.slug
|
||||
display = @modPack.findItemDisplay @model.slug
|
||||
|
||||
@_imageLoader.load display.iconUrl, @$icon
|
||||
@imageLoader.load display.iconUrl, @$icon
|
||||
@$name.html display.itemName
|
||||
@$nameLink.attr 'href', display.itemUrl
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ module.exports = class ItemGroupController extends BaseController
|
||||
delay += @_delayStep
|
||||
else
|
||||
controller.model = item
|
||||
controller.refresh()
|
||||
controllerIndex += 1
|
||||
|
||||
while @_itemControllers.length > controllerIndex
|
||||
|
||||
@@ -57,15 +57,17 @@ module.exports = class ItemPageController extends PageController
|
||||
imageLoader: @imageLoader
|
||||
modPack: @modPack
|
||||
|
||||
@$usedAsToolToMakeSection = @$('.usedAsToolToMake')
|
||||
@$byline = @$('.byline')
|
||||
@$bylineLink = @$('.byline a')
|
||||
@$craftingPlanLink = @$('a.craftingPlan')
|
||||
@$descriptionPanel = @$('.description .panel')
|
||||
@$descriptionSection = @$('.description')
|
||||
@$name = @$('h1.name')
|
||||
@$recipeContainer = @$('.recipes .panel')
|
||||
@$recipesSection = @$('.recipes')
|
||||
@$similarSection = @$('.similar')
|
||||
@$titleImage = @$('.titleImage img')
|
||||
@$usedAsToolToMakeSection = @$('.usedAsToolToMake')
|
||||
@$usedToMakeSection = @$('.usedToMake')
|
||||
super
|
||||
|
||||
@@ -84,6 +86,7 @@ module.exports = class ItemPageController extends PageController
|
||||
@$el.slideUp duration:Duration.normal
|
||||
|
||||
@_refreshByline()
|
||||
@_refreshDescription()
|
||||
@_refreshRecipes()
|
||||
@_refreshSimilarItems()
|
||||
@_refreshUsedAsToolToMake()
|
||||
@@ -100,15 +103,6 @@ module.exports = class ItemPageController extends PageController
|
||||
|
||||
# Private Methods ##############################################################################
|
||||
|
||||
_refreshUsedAsToolToMake: ->
|
||||
@_usedAsToolToMakeController.title = 'Used as Tool to Make'
|
||||
|
||||
@_usedAsToolToMakeController.model = @model.findToolForRecipes()
|
||||
if @_usedAsToolToMakeController.model?
|
||||
@$usedAsToolToMakeSection.slideDown duration:Duration.normal
|
||||
else
|
||||
@$usedAsToolToMakeSection.slideUp duration:Duration.normal
|
||||
|
||||
_refreshByline: ->
|
||||
mod = @model.item?.modVersion?.mod
|
||||
if mod?.name?.length > 0
|
||||
@@ -118,14 +112,15 @@ module.exports = class ItemPageController extends PageController
|
||||
else
|
||||
@$byline.fadeOut duration:Duration.fast
|
||||
|
||||
_refreshUsedToMake: ->
|
||||
@_usedToMakeController.title = 'Used to Make'
|
||||
|
||||
@_usedToMakeController.model = @model.findComponentInItems()
|
||||
if @_usedToMakeController.model?
|
||||
@$usedToMakeSection.slideDown duration:Duration.normal
|
||||
_refreshDescription: ->
|
||||
logger.debug "refreshing description"
|
||||
logger.debug "item.description: #{@model?.item?.description}"
|
||||
description = @model.compileDescription()
|
||||
if description?
|
||||
@$descriptionPanel.html description
|
||||
@$descriptionSection.slideDown duration:Duration.normal
|
||||
else
|
||||
@$usedToMakeSection.slideUp duration:Duration.normal
|
||||
@$descriptionSection.slideUp duration:Duration.normal
|
||||
|
||||
_refreshRecipes: ->
|
||||
@_recipeControllers ?= []
|
||||
@@ -165,10 +160,35 @@ module.exports = class ItemPageController extends PageController
|
||||
else
|
||||
@$similarSection.slideUp duration:Duration.normal
|
||||
|
||||
_resolveItemSlug: ->
|
||||
item = @modPack.findItem @_itemSlug, includeDisabled:false
|
||||
if item? and not ItemSlug.equal item.slug, @_itemSlug
|
||||
router.navigate Url.item(modSlug:item.slug.mod, itemSlug:item.slug.item), trigger:true
|
||||
return
|
||||
_refreshUsedAsToolToMake: ->
|
||||
@_usedAsToolToMakeController.title = 'Used as Tool to Make'
|
||||
|
||||
@model.item = item
|
||||
@_usedAsToolToMakeController.model = @model.findToolForRecipes()
|
||||
if @_usedAsToolToMakeController.model?
|
||||
@$usedAsToolToMakeSection.slideDown duration:Duration.normal
|
||||
else
|
||||
@$usedAsToolToMakeSection.slideUp duration:Duration.normal
|
||||
|
||||
_refreshUsedToMake: ->
|
||||
@_usedToMakeController.title = 'Used to Make'
|
||||
|
||||
@_usedToMakeController.model = @model.findComponentInItems()
|
||||
if @_usedToMakeController.model?
|
||||
@$usedToMakeSection.slideDown duration:Duration.normal
|
||||
else
|
||||
@$usedToMakeSection.slideUp duration:Duration.normal
|
||||
|
||||
_resolveItemSlug: ->
|
||||
return if @model.item?
|
||||
|
||||
item = @modPack.findItem @_itemSlug, includeDisabled:false
|
||||
if item?
|
||||
if not ItemSlug.equal item.slug, @_itemSlug
|
||||
router.navigate Url.item(modSlug:item.slug.mod, itemSlug:item.slug.item), trigger:true
|
||||
return
|
||||
|
||||
@model.item = item
|
||||
item.fetch()
|
||||
item.on Event.sync, =>
|
||||
logger.debug "item loaded"
|
||||
@refresh()
|
||||
|
||||
@@ -10,6 +10,7 @@ BaseModel = require './base_model'
|
||||
ItemSlug = require './item_slug'
|
||||
Recipe = require './recipe'
|
||||
StringBuilder = require './string_builder'
|
||||
{Url} = require '../constants'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
@@ -57,6 +58,18 @@ module.exports = class Item extends BaseModel
|
||||
Object.defineProperties @prototype,
|
||||
isCraftable: {get:@prototype.getIsCraftable}
|
||||
|
||||
# Backbone.Model Overrides #####################################################################
|
||||
|
||||
parse: (text)->
|
||||
ItemParser = require './item_parser' # to avoid require cycles
|
||||
@_parser ?= new ItemParser model:this
|
||||
@_parser.parse text
|
||||
|
||||
return null # prevent calling `set`
|
||||
|
||||
url: ->
|
||||
return Url.itemData modSlug:@slug.mod, itemSlug:@slug.item
|
||||
|
||||
# Object Overrides #############################################################################
|
||||
|
||||
toString: ->
|
||||
|
||||
@@ -20,6 +20,10 @@ module.exports = class ItemPage extends BaseModel
|
||||
|
||||
# Property Methods #############################################################################
|
||||
|
||||
compileDescription: ->
|
||||
return null unless @item?.description?
|
||||
return markdown.parse @item.description
|
||||
|
||||
findComponentInItems: ->
|
||||
return @_findRecipesMatching (recipe)=> recipe.requires @item.slug
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
###
|
||||
Crafting Guide - item_parser.coffee
|
||||
|
||||
Copyright (c) 2014-2015 by Redwood Labs
|
||||
All rights reserved.
|
||||
###
|
||||
|
||||
VersionedParserBase = require './versioned_parser_base'
|
||||
ItemParserV1 = require './parser_versions/item_parser_v1'
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
module.exports = class ItemParser extends VersionedParserBase
|
||||
|
||||
# VersionedParserBase Overrides ################################################################
|
||||
|
||||
_createParsers: (options)->
|
||||
return result =
|
||||
'1': new ItemParserV1 options
|
||||
@@ -171,7 +171,7 @@ module.exports = class ModVersion extends BaseModel
|
||||
return null # prevent calling `set`
|
||||
|
||||
url: ->
|
||||
return Url.modVersion modSlug:@modSlug, modVersion:@version
|
||||
return Url.modVersionData modSlug:@modSlug, modVersion:@version
|
||||
|
||||
# Object Overrides #############################################################################
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ module.exports = class CommandParserVersionBase
|
||||
line = line.trim()
|
||||
return [] if line.length is 0
|
||||
|
||||
hereDoc = @_parseHereDoc line
|
||||
[line, hereDoc] = @_parseHereDoc line
|
||||
|
||||
lineParts = (part.trim() for part in line.split(';'))
|
||||
commands = []
|
||||
@@ -89,8 +89,10 @@ module.exports = class CommandParserVersionBase
|
||||
if not match? then throw new Error "Expected <command>: <args>, but found: \"#{linePart}\""
|
||||
|
||||
args = []
|
||||
args = (s.trim() for s in match[2].split(',')) if match[2]?
|
||||
args.push hereDoc if hereDoc
|
||||
args = (s for s in match[2].split(',') when s.length > 0) if match[2]?
|
||||
args = (s.trim() for s in args)
|
||||
args = (s for s in args when s.length > 0)
|
||||
args.push hereDoc if hereDoc?
|
||||
commands.push name:match[1], args:args
|
||||
|
||||
return commands
|
||||
@@ -107,9 +109,11 @@ module.exports = class CommandParserVersionBase
|
||||
|
||||
_parseHereDoc: (line)->
|
||||
hereDocIndex = line.indexOf '<<-'
|
||||
return null unless hereDocIndex isnt -1
|
||||
return [line, null] unless hereDocIndex isnt -1
|
||||
|
||||
hereDocStopText = line[hereDocIndex+3...line.length]
|
||||
line = line[0...hereDocIndex]
|
||||
|
||||
hereDocLines = []
|
||||
while true
|
||||
@_lineNumber += 1
|
||||
@@ -120,11 +124,11 @@ module.exports = class CommandParserVersionBase
|
||||
hereDocLines.push nextLine
|
||||
|
||||
shortestIndent = Number.MAX_VALUE
|
||||
for line in hereDocLines
|
||||
shortestIndent = Math.min line.match(/( *).*/)[1].length, shortestIndent
|
||||
for hereDocLine in hereDocLines
|
||||
shortestIndent = Math.min hereDocLine.match(/( *).*/)[1].length, shortestIndent
|
||||
|
||||
for i in [0...hereDocLines.length]
|
||||
hereDocLines[i] = hereDocLines[i][shortestIndent..]
|
||||
|
||||
return null unless hereDocLines.length > 0
|
||||
return hereDocLines.join '\n'
|
||||
return [line, null] unless hereDocLines.length > 0
|
||||
return [line, hereDocLines.join('\n')]
|
||||
|
||||
@@ -22,16 +22,17 @@ module.exports = class ItemParserV1 extends CommandParserVersionBase
|
||||
# Command Methods ##############################################################################
|
||||
|
||||
_command_description: (textParts...)->
|
||||
@_rawData.text ?= ''
|
||||
@_rawData.text += textParts.join ', '
|
||||
@_rawData.description ?= ''
|
||||
@_rawData.description += textParts.join ', '
|
||||
|
||||
_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_video: (youTubeId, name)->
|
||||
_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 ?= []
|
||||
@@ -40,6 +41,6 @@ module.exports = class ItemParserV1 extends CommandParserVersionBase
|
||||
# Object Building Methods ######################################################################
|
||||
|
||||
_buildItem: (rawData, model)->
|
||||
item.description = rawData.description if rawData.description
|
||||
item.officialUrl = rawData.officialUrl if rawData.officialUrl
|
||||
item.videos = rawData.videos if rawData.videos
|
||||
model.description = rawData.description if rawData.description
|
||||
model.officialUrl = rawData.officialUrl if rawData.officialUrl
|
||||
model.videos = rawData.videos if rawData.videos
|
||||
|
||||
@@ -21,25 +21,28 @@ describe 'command_parser_version_base.coffee', ->
|
||||
|
||||
it 'returns null for non-heredoc lines', ->
|
||||
result = parser._parseHereDoc 'foobar: baz'
|
||||
expect(result).to.be.null
|
||||
expect(result[1]).to.be.null
|
||||
|
||||
it 'identifies the right text for a real heredoc', ->
|
||||
parser._lines = ['command: <<-END', 'alpha', 'bravo', 'charlie', 'END', 'command1: arg2']
|
||||
parser._lineNumber = 1
|
||||
|
||||
result = parser._parseHereDoc parser._lines[0]
|
||||
result.should.equal 'alpha\nbravo\ncharlie'
|
||||
result[0].should.equal 'command: '
|
||||
result[1].should.equal 'alpha\nbravo\ncharlie'
|
||||
|
||||
it 'identifies an empty heredoc', ->
|
||||
parser._lines = ['command: <<-END', 'END']
|
||||
parser._lineNumber = 1
|
||||
|
||||
result = parser._parseHereDoc parser._lines[0]
|
||||
expect(result).to.be.null
|
||||
result[0].should.equal 'command: '
|
||||
expect(result[1]).to.be.null
|
||||
|
||||
it 'trims smallest leading whitespace', ->
|
||||
parser._lines = ['command: <<-END', ' alpha', ' bravo', ' charlie', 'END', 'command1: arg2']
|
||||
parser._lineNumber = 1
|
||||
|
||||
result = parser._parseHereDoc parser._lines[0]
|
||||
result.should.equal 'alpha\n bravo\ncharlie'
|
||||
result[0].should.equal 'command: '
|
||||
result[1].should.equal 'alpha\n bravo\ncharlie'
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ var buf = [];
|
||||
var jade_mixins = {};
|
||||
var jade_interp;
|
||||
|
||||
buf.push("<div class=\"view__item_page\"><div class=\"sidebar\"><div class=\"titleImage\"><a><img/></a></div><a class=\"craftingPlan externalLink\"><p>See Crafting Plan</p></a><script async src=\"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\"></script>\n<!-- Sidebar Skyscraper -->\n<ins class=\"adsbygoogle\"\n style=\"display:inline-block;width:160px;height:600px\"\n data-ad-client=\"ca-pub-6593013914878730\"\n data-ad-slot=\"7613920409\"></ins>\n<script>\n(adsbygoogle = window.adsbygoogle || []).push({});\n</script>\n</div><div class=\"mainBody\"><h1 class=\"name\"></h1><div class=\"byline\"><p>from <a></a></p></div><div class=\"description\"><p></p></div><div class=\"recipes section\"><h2>Recipes</h2><div class=\"panel\"></div></div><div class=\"usedToMake\"><div class=\"view__item_group\"></div></div><div class=\"usedAsToolToMake\"><div class=\"view__item_group\"></div></div><div class=\"similar\"><div class=\"view__item_group\"></div></div><div class=\"plan\"></div></div></div>");;return buf.join("");
|
||||
buf.push("<div class=\"view__item_page\"><div class=\"sidebar\"><div class=\"titleImage\"><a><img/></a></div><a class=\"craftingPlan externalLink\"><p>See Crafting Plan</p></a><script async src=\"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\"></script>\n<!-- Sidebar Skyscraper -->\n<ins class=\"adsbygoogle\"\n style=\"display:inline-block;width:160px;height:600px\"\n data-ad-client=\"ca-pub-6593013914878730\"\n data-ad-slot=\"7613920409\"></ins>\n<script>\n(adsbygoogle = window.adsbygoogle || []).push({});\n</script>\n</div><div class=\"mainBody\"><h1 class=\"name\"></h1><div class=\"byline\"><p>from <a></a></p></div><div class=\"description section\"><h2>Description</h2><div class=\"panel markdown\"></div></div><div class=\"recipes section\"><h2>Recipes</h2><div class=\"panel\"></div></div><div class=\"usedToMake\"><div class=\"view__item_group\"></div></div><div class=\"usedAsToolToMake\"><div class=\"view__item_group\"></div></div><div class=\"similar\"><div class=\"view__item_group\"></div></div><div class=\"plan\"></div></div></div>");;return buf.join("");
|
||||
};
|
||||
|
||||
this["JST"]["minimal_recipe"] = function template(locals) {
|
||||
|
||||
@@ -34,4 +34,5 @@ html
|
||||
script(src="/js/jquery.js")
|
||||
script(src="/js/backbone.js")
|
||||
script(src="/js/jade.js")
|
||||
script(src="/js/markdown.js")
|
||||
script(src="/js/when.js")
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
.mainBody
|
||||
h1.name
|
||||
.byline: p from <a></a>
|
||||
.description: p
|
||||
|
||||
.description.section
|
||||
h2 Description
|
||||
.panel.markdown
|
||||
|
||||
.recipes.section
|
||||
h2 Recipes
|
||||
|
||||
@@ -86,6 +86,7 @@ $layer-dialog: 1000;
|
||||
// Child Stylesheets ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@import 'classes';
|
||||
@import 'markdown';
|
||||
@import 'tags';
|
||||
@import 'views';
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Crafting Guide - markdown.scss
|
||||
|
||||
Copyright (C) 2015 by Redwood Labs
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
.markdown {
|
||||
|
||||
p {
|
||||
font-family: $font-family-normal;
|
||||
font-size: $font-size-normal;
|
||||
line-height: $font-size-normal + 0.25em;
|
||||
}
|
||||
|
||||
img {
|
||||
position: relative; left: 50%;
|
||||
@include transform(translateX(-50%));
|
||||
margin: 2em 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
@@ -31,15 +31,6 @@ All rights reserved.
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-bottom: 4em;
|
||||
|
||||
p {
|
||||
font-family: $font-family-normal;
|
||||
font-size: $font-size-large;
|
||||
}
|
||||
}
|
||||
|
||||
.recipes {
|
||||
display: none;
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,15 @@
|
||||
schema: 1
|
||||
|
||||
officialUrl: http://www.mod-buildcraft.com/wiki/doku.php?id=advanced_crafting_table
|
||||
|
||||
video: Z-Kl3IRjxE, Tutorial
|
||||
|
||||
description:<<-END
|
||||
The advanced crafting table is an improved version of the basic automatic crafting table. It contains an inventory
|
||||
for storing the input and an inventory for storing the outputs of the crafting process, making it potentially more
|
||||
easy and seamless to create large automatic crafting systems. The advanced crafting table requires 500 MJ to craft
|
||||
any recipe.
|
||||
|
||||

|
||||
|
||||
END
|
||||
Reference in New Issue
Block a user