├── index.js ├── .gitignore ├── .npmignore ├── .travis.yml ├── docs ├── public │ ├── fonts │ │ ├── aller-bold.eot │ │ ├── aller-bold.ttf │ │ ├── aller-bold.woff │ │ ├── aller-light.eot │ │ ├── aller-light.ttf │ │ ├── aller-light.woff │ │ ├── novecento-bold.eot │ │ ├── novecento-bold.ttf │ │ └── novecento-bold.woff │ └── stylesheets │ │ └── normalize.css ├── bionode-sra.html └── docco.css ├── cli.js ├── sra └── Makefile ├── LICENSE ├── test └── bionode-sra.js ├── package.json ├── README.md ├── CODE_OF_CONDUCT.md ├── lib └── bionode-sra.js └── CONTRIBUTING.md /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/bionode-sra') 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | coverage 4 | tmp 5 | sra/bin 6 | sra/build 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | coverage 4 | tmp 5 | sra/bin 6 | sra/build 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "7" 4 | after_script: 5 | - npm run coveralls 6 | -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-bold.eot -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-bold.ttf -------------------------------------------------------------------------------- /docs/public/fonts/aller-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-bold.woff -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-light.eot -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-light.ttf -------------------------------------------------------------------------------- /docs/public/fonts/aller-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/aller-light.woff -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/novecento-bold.eot -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/novecento-bold.ttf -------------------------------------------------------------------------------- /docs/public/fonts/novecento-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bionode/bionode-sra/master/docs/public/fonts/novecento-bold.woff -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var JSONStream = require('JSONStream') 3 | var minimist = require('minimist') 4 | var sra = require('./') 5 | var split = require('split') 6 | 7 | var args = minimist(process.argv.slice(2)) 8 | 9 | var lastArg = args._[args._.length - 1] 10 | var wantsStdin = false 11 | if (lastArg === '-') { 12 | wantsStdin = true 13 | args._.pop() 14 | } 15 | 16 | var command = args._[0] 17 | var srcFile = args._[1] 18 | var destDir = args._[2] || '.' 19 | 20 | var sraStream = sra(command)() 21 | 22 | sraStream.pipe(JSONStream.stringify(false)).pipe(process.stdout) 23 | 24 | if (srcFile) { sraStream.write([srcFile, destDir]) } 25 | 26 | if (wantsStdin) { 27 | process.stdin.setEncoding('utf8') 28 | process.stdin.pipe(split()).on('data', function (data) { 29 | if (data.trim() === '') { return } 30 | sraStream.write(data.trim()) 31 | }) 32 | } 33 | -------------------------------------------------------------------------------- /sra/Makefile: -------------------------------------------------------------------------------- 1 | # This downloads and builds the SRA Toolkit binaries. 2 | 3 | OS := $(shell uname) 4 | VERSION := 2.3.5-2 5 | 6 | ifeq ($(OS), Darwin) 7 | BUILD_TARGET := mac 8 | else ifeq ($(OS), Linux) 9 | BUILD_TARGET := linux 10 | endif 11 | 12 | all: build 13 | 14 | build: build_dir $(BUILD_TARGET) 15 | 16 | build_dir: 17 | mkdir -p build 18 | 19 | linux: build/sratoolkit.$(VERSION)-ubuntu64.tar.gz 20 | cd build; tar xzvf $( 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/bionode-sra.js: -------------------------------------------------------------------------------- 1 | var sra = require('../') 2 | var fs = require('fs') 3 | var request = require('request') 4 | var crypto = require('crypto') 5 | var test = require('tape') 6 | 7 | test('Extract fastq from SRA', function (t) { 8 | t.plan(1) 9 | var sraURL = 'http://ftp-trace.ncbi.nlm.nih.gov/sra/sra-instant/reads/ByRun/sra/SRR/SRR150/SRR1509835/SRR1509835.sra' 10 | var downloadSRA = request(sraURL) 11 | downloadSRA.pipe(fs.createWriteStream('test/SRR1509835.sra')) 12 | downloadSRA.on('complete', dumpFastq) 13 | function dumpFastq () { 14 | var fastqDump = sra('fastq-dump') 15 | var srcFile = 'test/SRR1509835.sra' 16 | var destDir = 'test/' 17 | fastqDump([srcFile, destDir]).on('data', fastqDumped) 18 | } 19 | function fastqDumped (data) { 20 | var sha256sum = crypto.createHash('sha256') 21 | var fastqPath = data.srcFile.replace('sra', 'fastq') 22 | var fastqFile = fs.createReadStream(fastqPath) 23 | fastqFile.on('data', function (d) { sha256sum.update(d) }) 24 | fastqFile.on('end', checkSum) 25 | function checkSum () { 26 | var sha256 = sha256sum.digest('hex') 27 | var hash = 'f13dd1b06542a0a5e2ce078f8ab123abfbd70fe49400cae66f430a2d980e42d9' 28 | var msg = 'should take a srcFile and destDir strings and extract a fastq' 29 | t.equal(sha256, hash, msg) 30 | } 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bionode-sra", 3 | "description": "A Node.js wrapper for SRA Toolkit.", 4 | "version": "2.0.0", 5 | "homepage": "http://github.com/bionode/bionode-sra", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/bionode/bionode-sra.git" 9 | }, 10 | "author": { 11 | "name": "Bruno Vieira", 12 | "email": "mail@bmpvieira.com" 13 | }, 14 | "dependencies": { 15 | "JSONStream": "^1.3.1", 16 | "minimist": "^1.2.0", 17 | "split": "^1.0.0", 18 | "through2": "^2.0.3" 19 | }, 20 | "devDependencies": { 21 | "coveralls": "~2.13.1", 22 | "dependency-check": "^2.8.0", 23 | "docco": "~0.7.0", 24 | "istanbul": "~0.4.5", 25 | "request": "^2.81.0", 26 | "standard": "^10.0.2", 27 | "tap-spec": "^4.1.1", 28 | "tape": "^4.6.3", 29 | "testling": "^1.7.1" 30 | }, 31 | "keywords": [ 32 | "bio", 33 | "biology", 34 | "bionode", 35 | "bioinformatics", 36 | "download", 37 | "ftp", 38 | "wrapper", 39 | "installer", 40 | "streams", 41 | "cli" 42 | ], 43 | "main": "index.js", 44 | "bin": { 45 | "bionode-sra": "cli.js" 46 | }, 47 | "scripts": { 48 | "test": "standard && dependency-check . && node test/bionode-sra.js | tap-spec && rm -rf test/SRR1509835.*", 49 | "build-docs": "docco ./lib/bionode-sra.js", 50 | "coverage": "istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec && rm -rf ./coverage", 51 | "coveralls": "istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage" 52 | }, 53 | "license": "MIT" 54 | } 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | bionode logo 4 | 5 |
6 | bionode.io 7 |

8 | 9 | 10 | # bionode-sra 11 | 12 | > A Node.js wrapper for SRA Toolkit. 13 | 14 | [![npm](https://img.shields.io/npm/v/bionode-sra.svg?style=flat-square)](http://npmjs.org/package/bionode-sra) 15 | [![Travis](https://img.shields.io/travis/bionode/bionode-sra.svg?style=flat-square)](https://travis-ci.org/bionode/bionode-sra) 16 | [![Coveralls](https://img.shields.io/coveralls/bionode/bionode-sra.svg?style=flat-square)](http://coveralls.io/r/bionode/bionode-sra) 17 | [![Dependencies](http://img.shields.io/david/bionode/bionode-sra.svg?style=flat-square)](http://david-dm.org/bionode/bionode-sra) 18 | [![npm](https://img.shields.io/npm/dt/bionode-sra.svg?style=flat-square)](https://www.npmjs.com/package/bionode-sra) 19 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?style=flat-square)](https://gitter.im/bionode/bionode) 20 | 21 | 22 | ## Install 23 | 24 | You need to install the latest Node.JS first, please check [nodejs.org](http://nodejs.org) or do the following: 25 | 26 | ```bash 27 | # Ubuntu 28 | sudo apt-get install npm 29 | # Mac 30 | brew install node 31 | # Both 32 | npm install -g n 33 | n stable 34 | ``` 35 | 36 | To use `bionode-sra` as a command line tool, you can install it globally with `-g`. 37 | 38 | ```bash 39 | npm install bionode-sra -g 40 | ``` 41 | 42 | Or, if you want to use it as a JavaScript library, you need to install it in your local project folder inside the `node_modules` directory by doing the same command **without** `-g`. 43 | 44 | ```bash 45 | npm i bionode-sra # 'i' can be used as shortcut to 'install' 46 | ``` 47 | 48 | 49 | ## Usage 50 | 51 | If you're using bionode-sra with Node.js, you can require the module: 52 | 53 | ```js 54 | var sra = require('bionode-sra') 55 | var fastqDump = sra('fastq-dump') 56 | fastqDump('SRR1509835.sra') 57 | ``` 58 | 59 | Please read the [documentation](http://rawgit.com/bionode/bionode-sra/master/docs/bionode-sra.html) for the methods exposed by bionode. 60 | 61 | ### Command line examples 62 | ```sh 63 | $ bionode-sra fastq-dump SRR1509835.sra 64 | $ bionode-sra fastq-dump SRR1509835.sra fastqOutputDirectory 65 | ``` 66 | 67 | 68 | 69 | ## Documentation 70 | 71 | Check our documentation at [doc.bionode.io](http://doc.bionode.io) or do: 72 | 73 | ```bash 74 | bionode-sra --help 75 | ``` 76 | 77 | 78 | ## Contributing 79 | 80 | We welcome all kinds of contributions at all levels of experience, please read the [CONTRIBUTING.md](CONTRIBUTING.md) to get started! 81 | 82 | 83 | ## Communication channels 84 | 85 | Don't be shy! Come talk to us :smiley: 86 | 87 | * **Email** [mail@bionode.io](mailto:mail@bionode.io) 88 | * **Chat room** [http://gitter.im/bionode/bionode](http://gitter.im/bionode/bionode) 89 | * **IRC** #bionode on Freenode 90 | * **Twitter** [@bionode](http://twitter.com/@bionode) 91 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at mail@bionode.io. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /lib/bionode-sra.js: -------------------------------------------------------------------------------- 1 | // # bionode-sra 2 | // > A Node.js wrapper for SRA Toolkit. 3 | // > 4 | // > doi: [?](?) 5 | // > author: [Bruno Vieira](http://bmpvieira.com) 6 | // > email: 7 | // > license: [MIT](https://raw.githubusercontent.com/bionode/bionode-sra/master/LICENSE) 8 | // 9 | // --- 10 | // 11 | // ## Usage 12 | // This module can be used in Node.js as described further below, or as a command line tool. 13 | // Examples: 14 | // 15 | // $ npm install -g bionode-sra 16 | // 17 | // # bionode-sra [command] [arguments...] 18 | // $ bionode-sra fastq-dump SRR1509835.sra 19 | // $ bionode-sra fastq-dump SRR1509835.sra fastqOutputDirectory 20 | 21 | var path = require('path') 22 | var spawn = require('child_process').spawn 23 | var through = require('through2') 24 | 25 | module.exports = exports = SRA 26 | 27 | // ## SRA 28 | // Takes a SRA toolkit command and returns a Stream that accepts arguments for it. 29 | // For example, for ```fastq-dump```, arguments can be an array with ```[srcSRA, destDir]```, 30 | // a string like ```'srcSRA destDir'```. If ```destDir``` is omitted, the current directory will be used. 31 | // 32 | // var sra = require('bionode-sra') 33 | // var fastqDump = sra('fastq-dump')() 34 | // fastqDump.on('data', console.log) 35 | // fastqDump.write(['SRR1509835.sra', 'fastqOutDir']) 36 | // => { srcFile: 'SRR1509835.sra', 37 | // command: 'fastq-dump', 38 | // destDir: 'fastqOutDir' } 39 | // 40 | // A callback style can also be used: 41 | // 42 | // var fastqDump = sra('fastq-dump') 43 | // fastqDump('SRR1509835.sra fastqOutDir', function(err, data) { 44 | // console.log(data) 45 | // }) 46 | // 47 | // Or pipes, for example, from a file with just a list of SRA file names: 48 | // 49 | // var split = require('split') 50 | // var fastqDump = sra('fastq-dump')() 51 | // fs.createReadStream('sraFilesList.txt') 52 | // .pipe(split()) 53 | // .pipe(fastqDump) 54 | 55 | function SRA (command) { 56 | command = command || 'fastq-dump' 57 | 58 | return sraStream 59 | 60 | function sraStream (srcFileDestDir, callback) { 61 | var stream = through.obj(transform) 62 | if (srcFileDestDir) { stream.write(srcFileDestDir); stream.end() } 63 | if (callback) { 64 | stream.on('data', function (data) { 65 | callback(null, data) 66 | }) 67 | stream.on('error', callback) 68 | } 69 | return stream 70 | 71 | function transform (obj, enc, next) { 72 | var self = this 73 | 74 | try { 75 | var parsedObj = JSON.parse(obj) 76 | if (parsedObj.status === 'completed') { 77 | obj = [parsedObj.path, path.dirname(parsedObj.path)] 78 | } else { 79 | return next() 80 | } 81 | } catch (e) {} 82 | 83 | if (typeof obj === 'string') { obj = obj.split(' ') } 84 | 85 | if (obj.length > 2) { self.emit('error', new Error('Too many arguments')); next() } 86 | 87 | if (obj.length === 1) { obj.push('.') } 88 | 89 | // var sraPath = path.join(__dirname, '../sra/bin/' + command) 90 | var srcFile = obj[0] 91 | var destDir = obj[1] 92 | var options 93 | if (destDir === '.') { 94 | options = [srcFile] 95 | } else { 96 | options = [srcFile, '-O', destDir] 97 | } 98 | var sra = spawn(command, options) 99 | 100 | sra.stderr.on('data', function (data) { 101 | self.emit('error', new Error(data.toString())) 102 | next() 103 | }) 104 | 105 | sra.on('close', function (code) { 106 | if (code) { 107 | self.emit('error', new Error('Unknown error, check that "' + obj[0] + '" exists')) 108 | } else { 109 | var output = { 110 | srcFile: obj[0], 111 | command: command, 112 | destDir: obj[1] 113 | } 114 | if (command === 'fastq-dump') { 115 | output.destFile = output.srcFile.replace('.sra', '.fastq') 116 | } 117 | self.push(output) 118 | next() 119 | } 120 | }) 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Bionode 2 | 3 | Thank you for your interest in contributing to Bionode :tada:! 4 | 5 | Bionode is an Open Source community that aims at building highly reusable code and tools for bioinformatics by leveraging the Node.JS ecosystem. We use Node.JS Streams to process big genomic data. 6 | 7 | We welcome all kinds of contributions at all levels of experience, either code, knowledge, questions or suggestions. Many of our goals and GitHub issues do not require biology knowledge (e.g. very technical, coding) and some don't even require JavaScript knowledge (e.g. events, community, documentation). 8 | 9 | This document has a set of guidelines for contributing to Bionode on GitHub. These are guidelines, not rules. This guide is meant to make it easier for you to get involved. 10 | 11 | * [Participation guidelines](#participation-guidelines) 12 | * [What we're working on](#what-were-working-on) 13 | * [How to submit changes](#how-to-submit-changes) 14 | * [How to report bugs](#how-to-report-bugs) 15 | * [Communication channels](#communication-channels) 16 | 17 | ## Participation guidelines 18 | 19 | This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [mail@bionode.io](mailto:mail@bionode.io). 20 | 21 | ## What we're working on 22 | 23 | Take a look at the GitHub issues in our organisation wide project board at [project.bionode.io](http://project.bionode.io). Here's what each column means: 24 | * **Backlog** All the issues we have open (sorted by most recent). You'll find a lot in here and maybe something you could help us with. 25 | * **Next** What we want to work on next! Picking something to solve here would be greatly appreciated!! 26 | * **In Progress** Things we are currently working on, come help us! The person assigned to each issue is the one in charge and who you can ask any question. 27 | * **Done** Solved issues (sorted by closed date). Here you can check what we've been up to in the past. 28 | 29 | If you want to have a view of where all of this is going in the long run, check out our [Roadmap issue](https://github.com/bionode/bionode/issues/35), where we discuss our vision. 30 | 31 | ## How to submit changes 32 | 33 | Each bionode tool and library has its own repository (like a folder). 34 | Once you've identified one of the issues above that you feel you can contribute to, you're ready to make a change to the repository of that issue! However, it's always a good idea to [talk to us first](#communication-channels). Specially if you intend to take on something big, just to make sure we're on the same track. :wink: 35 | 36 | 1. **[Fork](https://help.github.com/articles/fork-a-repo/) the repository** that the issue belongs to. This makes your own version of the tool/library that you can edit and use. If you were invited to the [Bionode organisation](https://github.com/orgs/bionode/people) on GitHub, you can just `git clone` the repo and use a `git branch` instead of `forking`. 37 | 2. **[Make your changes](https://guides.github.com/activities/forking/#making-changes)**! You can do this in the GitHub interface on your own local machine. Once you're happy with your changes... 38 | 3. **Submit a [pull request](https://help.github.com/articles/proposing-changes-to-a-project-with-pull-requests/)**. This opens a discussion around your project and lets the project lead know you are proposing changes. 39 | 40 | First time contributing to open source? Check out this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). 41 | 42 | ## How to report bugs 43 | 44 | Any general Bionode bug or question should be reported on the issue tracker of [bionode/bionode](https://github.com/bionode/bionode/issues). Anything that is specific to one of the tools, e.g. `bionode-ncbi`, should be reported under [that tool issue tracker](https://github.com/bionode/bionode-ncbi). 45 | 46 | ## Communication channels 47 | 48 | Don't be shy! Come talk to us :smiley: 49 | 50 | * **Email** [mail@bionode.io](mailto:mail@bionode.io) 51 | * **Chat room** [http://gitter.im/bionode/bionode](http://gitter.im/bionode/bionode) 52 | * **IRC** #bionode on Freenode 53 | * **Twitter** [@bionode](http://twitter.com/@bionode) 54 | 55 | ## Node.JS specific commands 56 | If you're new to Node.JS we highly recommend checking the [NodeSchool workshop](https://nodeschool.io/#workshopper-list) that you can install and run in your command line. Example: 57 | 58 | ```bash 59 | npm install -g learnyounode 60 | learnyounode 61 | ``` 62 | 63 | To install a local version of a bionode tool that you are modifying (e.g. bionode-ncbi): 64 | 65 | ```bash 66 | git clone git@github.com:bionode/bionode-ncbi.git 67 | cd bionode-ncbi 68 | npm install # Install all dependencies defined in the package.json file 69 | npm link # Setup bionode-ncbi in your PATH to point to this local version 70 | ``` 71 | 72 | You can now modify the code in the `bionode-ncbi` folder and test the effect of those changes when you run the `bionode-ncbi` command in your terminal. 73 | 74 | To run a bionode tool suite of tests and check their code coverage, you can do: 75 | 76 | ```bash 77 | npm test 78 | npm run coverage 79 | ``` 80 | 81 | To rebuild and minify a bionode module for the browser (if supported) do: 82 | 83 | ```bash 84 | npm run build-browser 85 | ``` 86 | 87 | To rebuild the documentation using the comments in the code do: 88 | 89 | ```sh 90 | npm run build-docs 91 | ``` 92 | 93 | # Style guide 94 | We currently recommend using the [JavaScript Standard Style](https://github.com/feross/standard) to check your code. You can run it in the folder you're working (see below) and install it as an extension for your text editor (e.g. [Atom](https://atom.io/packages/linter-js-standard) or [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs)). 95 | 96 | ```bash 97 | npm install -g standard 98 | standard 99 | ``` 100 | 101 | # Testing 102 | We use [tape](https://github.com/substack/tape) with [tape-nock](https://github.com/Flet/tape-nock) for testing. Code coverage is checked with [istanbul](https://github.com/gotwarlost/istanbul). 103 | -------------------------------------------------------------------------------- /docs/public/stylesheets/normalize.css: -------------------------------------------------------------------------------- 1 | /*! normalize.css v2.0.1 | MIT License | git.io/normalize */ 2 | 3 | /* ========================================================================== 4 | HTML5 display definitions 5 | ========================================================================== */ 6 | 7 | /* 8 | * Corrects `block` display not defined in IE 8/9. 9 | */ 10 | 11 | article, 12 | aside, 13 | details, 14 | figcaption, 15 | figure, 16 | footer, 17 | header, 18 | hgroup, 19 | nav, 20 | section, 21 | summary { 22 | display: block; 23 | } 24 | 25 | /* 26 | * Corrects `inline-block` display not defined in IE 8/9. 27 | */ 28 | 29 | audio, 30 | canvas, 31 | video { 32 | display: inline-block; 33 | } 34 | 35 | /* 36 | * Prevents modern browsers from displaying `audio` without controls. 37 | * Remove excess height in iOS 5 devices. 38 | */ 39 | 40 | audio:not([controls]) { 41 | display: none; 42 | height: 0; 43 | } 44 | 45 | /* 46 | * Addresses styling for `hidden` attribute not present in IE 8/9. 47 | */ 48 | 49 | [hidden] { 50 | display: none; 51 | } 52 | 53 | /* ========================================================================== 54 | Base 55 | ========================================================================== */ 56 | 57 | /* 58 | * 1. Sets default font family to sans-serif. 59 | * 2. Prevents iOS text size adjust after orientation change, without disabling 60 | * user zoom. 61 | */ 62 | 63 | html { 64 | font-family: sans-serif; /* 1 */ 65 | -webkit-text-size-adjust: 100%; /* 2 */ 66 | -ms-text-size-adjust: 100%; /* 2 */ 67 | } 68 | 69 | /* 70 | * Removes default margin. 71 | */ 72 | 73 | body { 74 | margin: 0; 75 | } 76 | 77 | /* ========================================================================== 78 | Links 79 | ========================================================================== */ 80 | 81 | /* 82 | * Addresses `outline` inconsistency between Chrome and other browsers. 83 | */ 84 | 85 | a:focus { 86 | outline: thin dotted; 87 | } 88 | 89 | /* 90 | * Improves readability when focused and also mouse hovered in all browsers. 91 | */ 92 | 93 | a:active, 94 | a:hover { 95 | outline: 0; 96 | } 97 | 98 | /* ========================================================================== 99 | Typography 100 | ========================================================================== */ 101 | 102 | /* 103 | * Addresses `h1` font sizes within `section` and `article` in Firefox 4+, 104 | * Safari 5, and Chrome. 105 | */ 106 | 107 | h1 { 108 | font-size: 2em; 109 | } 110 | 111 | /* 112 | * Addresses styling not present in IE 8/9, Safari 5, and Chrome. 113 | */ 114 | 115 | abbr[title] { 116 | border-bottom: 1px dotted; 117 | } 118 | 119 | /* 120 | * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome. 121 | */ 122 | 123 | b, 124 | strong { 125 | font-weight: bold; 126 | } 127 | 128 | /* 129 | * Addresses styling not present in Safari 5 and Chrome. 130 | */ 131 | 132 | dfn { 133 | font-style: italic; 134 | } 135 | 136 | /* 137 | * Addresses styling not present in IE 8/9. 138 | */ 139 | 140 | mark { 141 | background: #ff0; 142 | color: #000; 143 | } 144 | 145 | 146 | /* 147 | * Corrects font family set oddly in Safari 5 and Chrome. 148 | */ 149 | 150 | code, 151 | kbd, 152 | pre, 153 | samp { 154 | font-family: monospace, serif; 155 | font-size: 1em; 156 | } 157 | 158 | /* 159 | * Improves readability of pre-formatted text in all browsers. 160 | */ 161 | 162 | pre { 163 | white-space: pre; 164 | white-space: pre-wrap; 165 | word-wrap: break-word; 166 | } 167 | 168 | /* 169 | * Sets consistent quote types. 170 | */ 171 | 172 | q { 173 | quotes: "\201C" "\201D" "\2018" "\2019"; 174 | } 175 | 176 | /* 177 | * Addresses inconsistent and variable font size in all browsers. 178 | */ 179 | 180 | small { 181 | font-size: 80%; 182 | } 183 | 184 | /* 185 | * Prevents `sub` and `sup` affecting `line-height` in all browsers. 186 | */ 187 | 188 | sub, 189 | sup { 190 | font-size: 75%; 191 | line-height: 0; 192 | position: relative; 193 | vertical-align: baseline; 194 | } 195 | 196 | sup { 197 | top: -0.5em; 198 | } 199 | 200 | sub { 201 | bottom: -0.25em; 202 | } 203 | 204 | /* ========================================================================== 205 | Embedded content 206 | ========================================================================== */ 207 | 208 | /* 209 | * Removes border when inside `a` element in IE 8/9. 210 | */ 211 | 212 | img { 213 | border: 0; 214 | } 215 | 216 | /* 217 | * Corrects overflow displayed oddly in IE 9. 218 | */ 219 | 220 | svg:not(:root) { 221 | overflow: hidden; 222 | } 223 | 224 | /* ========================================================================== 225 | Figures 226 | ========================================================================== */ 227 | 228 | /* 229 | * Addresses margin not present in IE 8/9 and Safari 5. 230 | */ 231 | 232 | figure { 233 | margin: 0; 234 | } 235 | 236 | /* ========================================================================== 237 | Forms 238 | ========================================================================== */ 239 | 240 | /* 241 | * Define consistent border, margin, and padding. 242 | */ 243 | 244 | fieldset { 245 | border: 1px solid #c0c0c0; 246 | margin: 0 2px; 247 | padding: 0.35em 0.625em 0.75em; 248 | } 249 | 250 | /* 251 | * 1. Corrects color not being inherited in IE 8/9. 252 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 253 | */ 254 | 255 | legend { 256 | border: 0; /* 1 */ 257 | padding: 0; /* 2 */ 258 | } 259 | 260 | /* 261 | * 1. Corrects font family not being inherited in all browsers. 262 | * 2. Corrects font size not being inherited in all browsers. 263 | * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome 264 | */ 265 | 266 | button, 267 | input, 268 | select, 269 | textarea { 270 | font-family: inherit; /* 1 */ 271 | font-size: 100%; /* 2 */ 272 | margin: 0; /* 3 */ 273 | } 274 | 275 | /* 276 | * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in 277 | * the UA stylesheet. 278 | */ 279 | 280 | button, 281 | input { 282 | line-height: normal; 283 | } 284 | 285 | /* 286 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 287 | * and `video` controls. 288 | * 2. Corrects inability to style clickable `input` types in iOS. 289 | * 3. Improves usability and consistency of cursor style between image-type 290 | * `input` and others. 291 | */ 292 | 293 | button, 294 | html input[type="button"], /* 1 */ 295 | input[type="reset"], 296 | input[type="submit"] { 297 | -webkit-appearance: button; /* 2 */ 298 | cursor: pointer; /* 3 */ 299 | } 300 | 301 | /* 302 | * Re-set default cursor for disabled elements. 303 | */ 304 | 305 | button[disabled], 306 | input[disabled] { 307 | cursor: default; 308 | } 309 | 310 | /* 311 | * 1. Addresses box sizing set to `content-box` in IE 8/9. 312 | * 2. Removes excess padding in IE 8/9. 313 | */ 314 | 315 | input[type="checkbox"], 316 | input[type="radio"] { 317 | box-sizing: border-box; /* 1 */ 318 | padding: 0; /* 2 */ 319 | } 320 | 321 | /* 322 | * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome. 323 | * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome 324 | * (include `-moz` to future-proof). 325 | */ 326 | 327 | input[type="search"] { 328 | -webkit-appearance: textfield; /* 1 */ 329 | -moz-box-sizing: content-box; 330 | -webkit-box-sizing: content-box; /* 2 */ 331 | box-sizing: content-box; 332 | } 333 | 334 | /* 335 | * Removes inner padding and search cancel button in Safari 5 and Chrome 336 | * on OS X. 337 | */ 338 | 339 | input[type="search"]::-webkit-search-cancel-button, 340 | input[type="search"]::-webkit-search-decoration { 341 | -webkit-appearance: none; 342 | } 343 | 344 | /* 345 | * Removes inner padding and border in Firefox 4+. 346 | */ 347 | 348 | button::-moz-focus-inner, 349 | input::-moz-focus-inner { 350 | border: 0; 351 | padding: 0; 352 | } 353 | 354 | /* 355 | * 1. Removes default vertical scrollbar in IE 8/9. 356 | * 2. Improves readability and alignment in all browsers. 357 | */ 358 | 359 | textarea { 360 | overflow: auto; /* 1 */ 361 | vertical-align: top; /* 2 */ 362 | } 363 | 364 | /* ========================================================================== 365 | Tables 366 | ========================================================================== */ 367 | 368 | /* 369 | * Remove most spacing between table cells. 370 | */ 371 | 372 | table { 373 | border-collapse: collapse; 374 | border-spacing: 0; 375 | } -------------------------------------------------------------------------------- /docs/bionode-sra.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bionode-sra 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
    15 | 16 | 17 | 18 |
  • 19 |
    20 | 21 |
    22 | 23 |
    24 |

    bionode-sra

    25 |
    26 |

    A Node.js wrapper for SRA Toolkit.

    27 |

    doi: ? 28 | author: Bruno Vieira 29 | email: mail@bmpvieira.com 30 | license: MIT

    31 |
    32 |
    33 | 34 |
    35 | 36 |
  • 37 | 38 | 39 |
  • 40 |
    41 | 42 |
    43 | 44 |
    45 |

    Usage

    46 |

    This module can be used in Node.js as described further below, or as a command line tool. 47 | Examples:

    48 |
    $ npm install -g bionode-sra
     49 | 
     50 | # bionode-sra [command] [arguments...]
     51 | $ bionode-sra fastq-dump SRR1509835.sra
     52 | $ bionode-sra fastq-dump SRR1509835.sra fastqOutputDirectory
     53 | 
    54 |
    55 | 56 |
     57 | 
     58 | var path = require('path')
     59 | var spawn = require('child_process').spawn
     60 | var through = require('through2')
     61 | 
     62 | module.exports = exports = SRA
    63 | 64 |
  • 65 | 66 | 67 |
  • 68 |
    69 | 70 |
    71 | 72 |
    73 |

    SRA

    74 |

    Takes a SRA toolkit command and returns a Stream that accepts arguments for it. 75 | For example, for fastq-dump, arguments can be an array with [srcSRA, destDir], 76 | a string like 'srcSRA destDir'. If destDir is omitted, the current directory will be used.

    77 |
    var sra = require('bionode-sra')
     78 | var fastqDump = sra('fastq-dump')()
     79 | fastqDump.on('data', console.log)
     80 | fastqDump.write(['SRR1509835.sra', 'fastqOutDir'])
     81 | => { srcFile: 'SRR1509835.sra',
     82 |      command: 'fastq-dump',
     83 |      destDir: 'fastqOutDir' }
     84 | 

    A callback style can also be used:

    85 |
    var fastqDump = sra('fastq-dump')
     86 | fastqDump('SRR1509835.sra fastqOutDir', function(err, data) {
     87 |   console.log(data)
     88 | })
     89 | 

    Or pipes, for example, from a file with just a list of SRA file names:

    90 |
    var split = require('split')
     91 | var fastqDump = sra('fastq-dump')()
     92 | fs.createReadStream('sraFilesList.txt')
     93 | .pipe(split())
     94 | .pipe(fastqDump)
     95 | 
    96 |
    97 | 98 |
     99 | function SRA(command) {
    100 |   var command = command || 'fastq-dump'
    101 | 
    102 |   return sraStream
    103 | 
    104 |   function sraStream(srcFileDestDir, callback) {
    105 |     var stream = through.obj(transform)
    106 |     if (srcFileDestDir) { stream.write(srcFileDestDir); stream.end() }
    107 |     if (callback) {
    108 |       stream.on('data', function(data) {
    109 |         callback(null, data)
    110 |       })
    111 |       stream.on('error', callback)
    112 |     }
    113 |     return stream
    114 | 
    115 |     function transform(obj, enc, next) {
    116 |       var self = this
    117 | 
    118 |       if (typeof obj === 'string') { obj = obj.split(' ') }
    119 | 
    120 |       if (obj.length > 2) { self.emit('error', new Error('Too many arguments')); next() }
    121 | 
    122 |       if (obj.length === 1) { obj.push('.') }
    123 | 
    124 |       var sraPath = path.join(__dirname, '../sra/bin/'+command)
    125 |       var srcFile = obj[0]
    126 |       var destDir = obj[1]
    127 |       var options
    128 |       if (destDir === '.') {
    129 |         options = [srcFile]
    130 |       }
    131 |       else {
    132 |         var options = [srcFile, '-O', destDir]
    133 |       }
    134 |       var sra = spawn(sraPath, options)
    135 | 
    136 |       sra.stderr.on('data', function(data) {
    137 |         self.emit('error', new Error(data.toString()))
    138 |         next()
    139 |       })
    140 | 
    141 |       sra.on('close', function(code) {
    142 |         if (code) {
    143 |           self.emit('error', new Error('Unknown error, check that "'+obj[0]+'" exists'))
    144 |         }
    145 |         else {
    146 |           self.push({srcFile: obj[0], command: command, destDir: obj[1]})
    147 |           next()
    148 |         }
    149 |       })
    150 |     }
    151 |   }
    152 | }
    153 | 154 |
  • 155 | 156 |
157 |
158 | 159 | 160 | -------------------------------------------------------------------------------- /docs/docco.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Typography ----------------------------*/ 2 | 3 | @font-face { 4 | font-family: 'aller-light'; 5 | src: url('public/fonts/aller-light.eot'); 6 | src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'), 7 | url('public/fonts/aller-light.woff') format('woff'), 8 | url('public/fonts/aller-light.ttf') format('truetype'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | 13 | @font-face { 14 | font-family: 'aller-bold'; 15 | src: url('public/fonts/aller-bold.eot'); 16 | src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'), 17 | url('public/fonts/aller-bold.woff') format('woff'), 18 | url('public/fonts/aller-bold.ttf') format('truetype'); 19 | font-weight: normal; 20 | font-style: normal; 21 | } 22 | 23 | @font-face { 24 | font-family: 'novecento-bold'; 25 | src: url('public/fonts/novecento-bold.eot'); 26 | src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'), 27 | url('public/fonts/novecento-bold.woff') format('woff'), 28 | url('public/fonts/novecento-bold.ttf') format('truetype'); 29 | font-weight: normal; 30 | font-style: normal; 31 | } 32 | 33 | /*--------------------- Layout ----------------------------*/ 34 | html { height: 100%; } 35 | body { 36 | font-family: "aller-light"; 37 | font-size: 14px; 38 | line-height: 18px; 39 | color: #30404f; 40 | margin: 0; padding: 0; 41 | height:100%; 42 | } 43 | #container { min-height: 100%; } 44 | 45 | a { 46 | color: #000; 47 | } 48 | 49 | b, strong { 50 | font-weight: normal; 51 | font-family: "aller-bold"; 52 | } 53 | 54 | p { 55 | margin: 15px 0 0px; 56 | } 57 | .annotation ul, .annotation ol { 58 | margin: 25px 0; 59 | } 60 | .annotation ul li, .annotation ol li { 61 | font-size: 14px; 62 | line-height: 18px; 63 | margin: 10px 0; 64 | } 65 | 66 | h1, h2, h3, h4, h5, h6 { 67 | color: #112233; 68 | line-height: 1em; 69 | font-weight: normal; 70 | font-family: "novecento-bold"; 71 | text-transform: uppercase; 72 | margin: 30px 0 15px 0; 73 | } 74 | 75 | h1 { 76 | margin-top: 40px; 77 | } 78 | 79 | hr { 80 | border: 0; 81 | background: 1px #ddd; 82 | height: 1px; 83 | margin: 20px 0; 84 | } 85 | 86 | pre, tt, code { 87 | font-size: 12px; line-height: 16px; 88 | font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; 89 | margin: 0; padding: 0; 90 | } 91 | .annotation pre { 92 | display: block; 93 | margin: 0; 94 | padding: 7px 10px; 95 | background: #fcfcfc; 96 | -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 97 | -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 98 | box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 99 | overflow-x: auto; 100 | } 101 | .annotation pre code { 102 | border: 0; 103 | padding: 0; 104 | background: transparent; 105 | } 106 | 107 | 108 | blockquote { 109 | border-left: 5px solid #ccc; 110 | margin: 0; 111 | padding: 1px 0 1px 1em; 112 | } 113 | .sections blockquote p { 114 | font-family: Menlo, Consolas, Monaco, monospace; 115 | font-size: 12px; line-height: 16px; 116 | color: #999; 117 | margin: 10px 0 0; 118 | white-space: pre-wrap; 119 | } 120 | 121 | ul.sections { 122 | list-style: none; 123 | padding:0 0 5px 0;; 124 | margin:0; 125 | } 126 | 127 | /* 128 | Force border-box so that % widths fit the parent 129 | container without overlap because of margin/padding. 130 | 131 | More Info : http://www.quirksmode.org/css/box.html 132 | */ 133 | ul.sections > li > div { 134 | -moz-box-sizing: border-box; /* firefox */ 135 | -ms-box-sizing: border-box; /* ie */ 136 | -webkit-box-sizing: border-box; /* webkit */ 137 | -khtml-box-sizing: border-box; /* konqueror */ 138 | box-sizing: border-box; /* css3 */ 139 | } 140 | 141 | 142 | /*---------------------- Jump Page -----------------------------*/ 143 | #jump_to, #jump_page { 144 | margin: 0; 145 | background: white; 146 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 147 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 148 | font: 16px Arial; 149 | cursor: pointer; 150 | text-align: right; 151 | list-style: none; 152 | } 153 | 154 | #jump_to a { 155 | text-decoration: none; 156 | } 157 | 158 | #jump_to a.large { 159 | display: none; 160 | } 161 | #jump_to a.small { 162 | font-size: 22px; 163 | font-weight: bold; 164 | color: #676767; 165 | } 166 | 167 | #jump_to, #jump_wrapper { 168 | position: fixed; 169 | right: 0; top: 0; 170 | padding: 10px 15px; 171 | margin:0; 172 | } 173 | 174 | #jump_wrapper { 175 | display: none; 176 | padding:0; 177 | } 178 | 179 | #jump_to:hover #jump_wrapper { 180 | display: block; 181 | } 182 | 183 | #jump_page { 184 | padding: 5px 0 3px; 185 | margin: 0 0 25px 25px; 186 | } 187 | 188 | #jump_page .source { 189 | display: block; 190 | padding: 15px; 191 | text-decoration: none; 192 | border-top: 1px solid #eee; 193 | } 194 | 195 | #jump_page .source:hover { 196 | background: #f5f5ff; 197 | } 198 | 199 | #jump_page .source:first-child { 200 | } 201 | 202 | /*---------------------- Low resolutions (> 320px) ---------------------*/ 203 | @media only screen and (min-width: 320px) { 204 | .pilwrap { display: none; } 205 | 206 | ul.sections > li > div { 207 | display: block; 208 | padding:5px 10px 0 10px; 209 | } 210 | 211 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 212 | padding-left: 30px; 213 | } 214 | 215 | ul.sections > li > div.content { 216 | overflow-x:auto; 217 | -webkit-box-shadow: inset 0 0 5px #e5e5ee; 218 | box-shadow: inset 0 0 5px #e5e5ee; 219 | border: 1px solid #dedede; 220 | margin:5px 10px 5px 10px; 221 | padding-bottom: 5px; 222 | } 223 | 224 | ul.sections > li > div.annotation pre { 225 | margin: 7px 0 7px; 226 | padding-left: 15px; 227 | } 228 | 229 | ul.sections > li > div.annotation p tt, .annotation code { 230 | background: #f8f8ff; 231 | border: 1px solid #dedede; 232 | font-size: 12px; 233 | padding: 0 0.2em; 234 | } 235 | } 236 | 237 | /*---------------------- (> 481px) ---------------------*/ 238 | @media only screen and (min-width: 481px) { 239 | #container { 240 | position: relative; 241 | } 242 | body { 243 | background-color: #F5F5FF; 244 | font-size: 15px; 245 | line-height: 21px; 246 | } 247 | pre, tt, code { 248 | line-height: 18px; 249 | } 250 | p, ul, ol { 251 | margin: 0 0 15px; 252 | } 253 | 254 | 255 | #jump_to { 256 | padding: 5px 10px; 257 | } 258 | #jump_wrapper { 259 | padding: 0; 260 | } 261 | #jump_to, #jump_page { 262 | font: 10px Arial; 263 | text-transform: uppercase; 264 | } 265 | #jump_page .source { 266 | padding: 5px 10px; 267 | } 268 | #jump_to a.large { 269 | display: inline-block; 270 | } 271 | #jump_to a.small { 272 | display: none; 273 | } 274 | 275 | 276 | 277 | #background { 278 | position: absolute; 279 | top: 0; bottom: 0; 280 | width: 350px; 281 | background: #fff; 282 | border-right: 1px solid #e5e5ee; 283 | z-index: -1; 284 | } 285 | 286 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 287 | padding-left: 40px; 288 | } 289 | 290 | ul.sections > li { 291 | white-space: nowrap; 292 | } 293 | 294 | ul.sections > li > div { 295 | display: inline-block; 296 | } 297 | 298 | ul.sections > li > div.annotation { 299 | max-width: 350px; 300 | min-width: 350px; 301 | min-height: 5px; 302 | padding: 13px; 303 | overflow-x: hidden; 304 | white-space: normal; 305 | vertical-align: top; 306 | text-align: left; 307 | } 308 | ul.sections > li > div.annotation pre { 309 | margin: 15px 0 15px; 310 | padding-left: 15px; 311 | } 312 | 313 | ul.sections > li > div.content { 314 | padding: 13px; 315 | vertical-align: top; 316 | border: none; 317 | -webkit-box-shadow: none; 318 | box-shadow: none; 319 | } 320 | 321 | .pilwrap { 322 | position: relative; 323 | display: inline; 324 | } 325 | 326 | .pilcrow { 327 | font: 12px Arial; 328 | text-decoration: none; 329 | color: #454545; 330 | position: absolute; 331 | top: 3px; left: -20px; 332 | padding: 1px 2px; 333 | opacity: 0; 334 | -webkit-transition: opacity 0.2s linear; 335 | } 336 | .for-h1 .pilcrow { 337 | top: 47px; 338 | } 339 | .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { 340 | top: 35px; 341 | } 342 | 343 | ul.sections > li > div.annotation:hover .pilcrow { 344 | opacity: 1; 345 | } 346 | } 347 | 348 | /*---------------------- (> 1025px) ---------------------*/ 349 | @media only screen and (min-width: 1025px) { 350 | 351 | body { 352 | font-size: 16px; 353 | line-height: 24px; 354 | } 355 | 356 | #background { 357 | width: 525px; 358 | } 359 | ul.sections > li > div.annotation { 360 | max-width: 525px; 361 | min-width: 525px; 362 | padding: 10px 25px 1px 50px; 363 | } 364 | ul.sections > li > div.content { 365 | padding: 9px 15px 16px 25px; 366 | } 367 | } 368 | 369 | /*---------------------- Syntax Highlighting -----------------------------*/ 370 | 371 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 372 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 373 | /* 374 | 375 | github.com style (c) Vasily Polovnyov 376 | 377 | */ 378 | 379 | pre code { 380 | display: block; padding: 0.5em; 381 | color: #000; 382 | background: #f8f8ff 383 | } 384 | 385 | pre .hljs-comment, 386 | pre .hljs-template_comment, 387 | pre .hljs-diff .hljs-header, 388 | pre .hljs-javadoc { 389 | color: #408080; 390 | font-style: italic 391 | } 392 | 393 | pre .hljs-keyword, 394 | pre .hljs-assignment, 395 | pre .hljs-literal, 396 | pre .hljs-css .hljs-rule .hljs-keyword, 397 | pre .hljs-winutils, 398 | pre .hljs-javascript .hljs-title, 399 | pre .hljs-lisp .hljs-title, 400 | pre .hljs-subst { 401 | color: #954121; 402 | /*font-weight: bold*/ 403 | } 404 | 405 | pre .hljs-number, 406 | pre .hljs-hexcolor { 407 | color: #40a070 408 | } 409 | 410 | pre .hljs-string, 411 | pre .hljs-tag .hljs-value, 412 | pre .hljs-phpdoc, 413 | pre .hljs-tex .hljs-formula { 414 | color: #219161; 415 | } 416 | 417 | pre .hljs-title, 418 | pre .hljs-id { 419 | color: #19469D; 420 | } 421 | pre .hljs-params { 422 | color: #00F; 423 | } 424 | 425 | pre .hljs-javascript .hljs-title, 426 | pre .hljs-lisp .hljs-title, 427 | pre .hljs-subst { 428 | font-weight: normal 429 | } 430 | 431 | pre .hljs-class .hljs-title, 432 | pre .hljs-haskell .hljs-label, 433 | pre .hljs-tex .hljs-command { 434 | color: #458; 435 | font-weight: bold 436 | } 437 | 438 | pre .hljs-tag, 439 | pre .hljs-tag .hljs-title, 440 | pre .hljs-rules .hljs-property, 441 | pre .hljs-django .hljs-tag .hljs-keyword { 442 | color: #000080; 443 | font-weight: normal 444 | } 445 | 446 | pre .hljs-attribute, 447 | pre .hljs-variable, 448 | pre .hljs-instancevar, 449 | pre .hljs-lisp .hljs-body { 450 | color: #008080 451 | } 452 | 453 | pre .hljs-regexp { 454 | color: #B68 455 | } 456 | 457 | pre .hljs-class { 458 | color: #458; 459 | font-weight: bold 460 | } 461 | 462 | pre .hljs-symbol, 463 | pre .hljs-ruby .hljs-symbol .hljs-string, 464 | pre .hljs-ruby .hljs-symbol .hljs-keyword, 465 | pre .hljs-ruby .hljs-symbol .hljs-keymethods, 466 | pre .hljs-lisp .hljs-keyword, 467 | pre .hljs-tex .hljs-special, 468 | pre .hljs-input_number { 469 | color: #990073 470 | } 471 | 472 | pre .hljs-builtin, 473 | pre .hljs-constructor, 474 | pre .hljs-built_in, 475 | pre .hljs-lisp .hljs-title { 476 | color: #0086b3 477 | } 478 | 479 | pre .hljs-preprocessor, 480 | pre .hljs-pi, 481 | pre .hljs-doctype, 482 | pre .hljs-shebang, 483 | pre .hljs-cdata { 484 | color: #999; 485 | font-weight: bold 486 | } 487 | 488 | pre .hljs-deletion { 489 | background: #fdd 490 | } 491 | 492 | pre .hljs-addition { 493 | background: #dfd 494 | } 495 | 496 | pre .hljs-diff .hljs-change { 497 | background: #0086b3 498 | } 499 | 500 | pre .hljs-chunk { 501 | color: #aaa 502 | } 503 | 504 | pre .hljs-tex .hljs-formula { 505 | opacity: 0.5; 506 | } 507 | --------------------------------------------------------------------------------