npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

anitomyjs

v1.5.3

Published

Node.js binding for the Anitomy anime video filename parsing library

Downloads

38

Readme

node.anitomy.js

License Linux & OSX Build Status Windows Build Status
NPM
node.anitomy.js is a Node.js binding for Anitomy a C++ library for parsing anime video filenames.

Installing

You can install node.anitomy.js as a dependency of your project using NPM like so, provided you have met the dependencies listed below.

> npm install --save anitomyjs

Dependencies

Example Usage

const anitomy = require('anitomyjs');

const filename = '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv';

const elems = anitomy.parseSync(filename);

console.log(elems.AnimeTitle + ' #' + elems.EpisodeNumber + 
            ' by ' + elems.ReleaseGroup);

Would output:

Toradora! #01 by TaigaSubs

API

parse(filenames[, options], callback)

Parses the filenames asynchronously.

  • filenames must be either a string, or an array of strings.
  • options is optional, if provided it must be an object, as set out here.
  • callback must be a function, will be called passing the resulting elements as the first parameter.
    • If filenames was an array, then the passed value will be an array of AnitomyElements, with the same ordering as filenames.
    • If filenames was a string, then the passed value will be an AnitomyElements.
const filename = '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv';
anitomy.parse(filename, function (elems) {
  console.log(elems.AnimeTitle + ' #' + elems.EpisodeNumber + 
              ' by ' + elems.ReleaseGroup);
});

Would output:

Toradora! #01 by TaigaSubs

parseSync(filenames[, options])

Parses the filenames synchronously.

  • filenames must be either a string, or an array of strings.
  • options is optional, if provided it must be an object, as set out here.
  • Returns:
    • If filenames was an array, then the returned value will be an array of AnitomyElements, with the same ordering as filenames.
    • If filenames was a string, then the returned value will be an AnitomyElements.
const filename = '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv';
const elems = anitomy.parseSync(filename);
console.log(elems.AnimeTitle + ' #' + elems.EpisodeNumber + 
            ' by ' + elems.ReleaseGroup);

Would output:

Toradora! #01 by TaigaSubs

parseEach(filenames[, options], callback)

Parses each of the individual filenames asynchronously, as opposed to parse which parses them all in bulk. As it is asynchronous there is no ordering ensured.

  • filenames must be either a string, or an array of strings.
  • options is optional, if provided it must be an object, as set out here.
  • callback must be a function, will be called when each filename is parsed, passing the filename and the resulting AnitomyElements as the first and second parameters respectively.
const filenames = [
  '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv',
  '[ANBU]_Princess_Lover!_-_01_[2048A39A].mkv',
  '[ANBU-Menclave]_Canaan_-_01_[1024x576_H.264_AAC][12F00E89].mkv',
  '[ANBU-umai]_Haiyoru!_Nyaru-Ani_[596DD8E6].mkv'
];
anitomy.parseEach(filenames, function (filename, elems) {
  console.log(filename + '\n\t=> ' + elems.AnimeTitle + ' #' + elems.EpisodeNumber + 
              ' by ' + elems.ReleaseGroup);
});

Would output (though not necessarily in this order):

[ANBU]_Princess_Lover!_-_01_[2048A39A].mkv
  => Princess Lover! #01 by ANBU
[ANBU-Menclave]_Canaan_-_01_[1024x576_H.264_AAC][12F00E89].mkv
  => Canaan #01 by ANBU-Menclave
[ANBU-umai]_Haiyoru!_Nyaru-Ani_[596DD8E6].mkv
  => Haiyoru! Nyaru-Ani #undefined by ANBU-umai
[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv
  => Toradora! #01 by TaigaSubs

parseEachSync(filenames[, options], callback)

Same as parseEach but synchronous, i.e. calls callback for each parsed filename, then returns. callback is ensured to be called in the same order as filenames.

  • filenames must be either a string, or an array of strings.
  • options is optional, if provided it must be an object, as set out here.
  • callback must be a function, will be called when each filename is parsed, passing the filename and the resulting AnitomyElements as the first and second parameters respectively.
const filenames = [
  '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv',
  '[ANBU]_Princess_Lover!_-_01_[2048A39A].mkv',
  '[ANBU-Menclave]_Canaan_-_01_[1024x576_H.264_AAC][12F00E89].mkv',
  '[ANBU-umai]_Haiyoru!_Nyaru-Ani_[596DD8E6].mkv'
];
anitomy.parseEachSync(filenames, function (filename, elems) {
  console.log(filename + '\n\t=> ' + elems.AnimeTitle + ' #' + elems.EpisodeNumber + 
              ' by ' + elems.ReleaseGroup);
});
console.log('parseEachSync completed');

Would output:

[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv
  => Toradora! #01 by TaigaSubs
[ANBU]_Princess_Lover!_-_01_[2048A39A].mkv
  => Princess Lover! #01 by ANBU
[ANBU-Menclave]_Canaan_-_01_[1024x576_H.264_AAC][12F00E89].mkv
  => Canaan #01 by ANBU-Menclave
[ANBU-umai]_Haiyoru!_Nyaru-Ani_[596DD8E6].mkv
  => Haiyoru! Nyaru-Ani #undefined by ANBU-umai
parseEachSync completed

Parse Options

Options are given in the form of an object, with any or all of the following properties set, if unset they default to these values (Anitomy's defaults):

{
  allowedDelimiters: ' _.&+,|',
  ignoredStrings: [],
  parseEpisodeNumber: true,
  parseEpisodeTitle: true,
  parseFileExtension: true,
  parseReleaseGroup: true
}

AnitomyElements

This object represents the parsed elements of the filename. With a property for each ElementCategory that it has a value for, the properties are immutable. In cases where there are multiple elements in a category the property's value will be an array.

AnitomyElements {
  AnimeTitle: 'Toradora!',
  AnimeYear: '2008',
  AudioTerm: 'FLAC',
  EpisodeNumber: '01',
  EpisodeTitle: 'Tiger and Dragon',
  FileChecksum: '1234ABCD',
  FileExtension: 'mkv',
  FileName: '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD]',
  ReleaseGroup: 'TaigaSubs',
  ReleaseVersion: '2',
  VideoResolution: '1280x720',
  VideoTerm: 'H.264' }

AnitomyElements#empty([category])

Returns true if the AnitomyElements has no category-value pairs.

  • category is optional, if provided must be a string representing an ElementCategory, return value will then be true if the AnitomyElements has no values for that category.
const filename = '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv';
const elems = anitomy.parseSync(filename);
/* -> AnitomyElements {
  AnimeTitle: 'Toradora!',
  AnimeYear: '2008',
  AudioTerm: 'FLAC',
  EpisodeNumber: '01',
  EpisodeTitle: 'Tiger and Dragon',
  FileChecksum: '1234ABCD',
  FileExtension: 'mkv',
  FileName: '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD]',
  ReleaseGroup: 'TaigaSubs',
  ReleaseVersion: '2',
  VideoResolution: '1280x720',
  VideoTerm: 'H.264' } */
const isEmpty = elems.empty();
// -> false
const hasNoVolumeNumber = elems.empty('VolumeNumber');
// -> true

AnitomyElements#count(category)

Returns the number of values associated with the category in this AnitomyElements.

const filename = 'Detective Conan - 316-317 [DCTP][2411959B].mkv';
const elems = anitomy.parseSync(filename);
/* -> AnitomyElements {
  AnimeTitle: 'Detective Conan',
  EpisodeNumber: [ '316', '317' ],
  FileChecksum: '2411959B',
  FileExtension: 'mkv',
  FileName: 'Detective Conan - 316-317 [DCTP][2411959B]',
  ReleaseGroup: 'DCTP' } */
const numOfEpNumbers = elems.count('EpisodeNumber');
// -> 2

AnitomyElements#size()

Returns the number of category-value pairs this AnitomyElements has.

const filename = '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD].mkv';
const elems = anitomy.parseSync(filename);
/* -> AnitomyElements {
  AnimeTitle: 'Toradora!',
  AnimeYear: '2008',
  AudioTerm: 'FLAC',
  EpisodeNumber: '01',
  EpisodeTitle: 'Tiger and Dragon',
  FileChecksum: '1234ABCD',
  FileExtension: 'mkv',
  FileName: '[TaigaSubs]_Toradora!_(2008)_-_01v2_-_Tiger_and_Dragon_[1280x720_H.264_FLAC][1234ABCD]',
  ReleaseGroup: 'TaigaSubs',
  ReleaseVersion: '2',
  VideoResolution: '1280x720',
  VideoTerm: 'H.264' } */
const size = elems.size();
// -> 12

AnitomyElements#get(category)

Returns the first value associated with the category in this AnitomyElements, or an empty string if none.

const filename = 'Detective Conan - 316-317 [DCTP][2411959B].mkv';
const elems = anitomy.parseSync(filename);
/* -> AnitomyElements {
  AnimeTitle: 'Detective Conan',
  EpisodeNumber: [ '316', '317' ],
  FileChecksum: '2411959B',
  FileExtension: 'mkv',
  FileName: 'Detective Conan - 316-317 [DCTP][2411959B]',
  ReleaseGroup: 'DCTP' } */
const firstEpNum = elems.get('EpisodeNumber');
// -> '316'

AnitomyElements#getAll(category)

Returns an array of all the values associated with the category in this AnitomyElements, or an empty array if none.

const filename = 'Detective Conan - 316-317 [DCTP][2411959B].mkv';
const elems = anitomy.parseSync(filename);
/* -> AnitomyElements {
  AnimeTitle: 'Detective Conan',
  EpisodeNumber: [ '316', '317' ],
  FileChecksum: '2411959B',
  FileExtension: 'mkv',
  FileName: 'Detective Conan - 316-317 [DCTP][2411959B]',
  ReleaseGroup: 'DCTP' } */
const epNums = elems.getAll('EpisodeNumber');
// -> [ '316', '317' ]

Element Categories

The element category names are the same as in anitomy::ElementCategory, without the anitomy::kElement prefix:

[
  'AnimeSeason',
  'AnimeSeasonPrefix',
  'AnimeTitle',
  'AnimeType',
  'AnimeYear',
  'AudioTerm',
  'DeviceCompatibility',
  'EpisodeNumber',
  'EpisodeNumberAlt',
  'EpisodePrefix',
  'EpisodeTitle',
  'FileChecksum',
  'FileExtension',
  'FileName',
  'Language',
  'Other',
  'ReleaseGroup',
  'ReleaseInformation',
  'ReleaseVersion',
  'Source',
  'Subtitles',
  'VideoResolution',
  'VideoTerm',
  'VolumeNumber',
  'VolumePrefix'
]

License

node.anitomy.js is licensed under Mozilla Public License 2.0.