UNPKG

ldpm-pubmed

Version:

pubmed as package.jsonld

1,215 lines (868 loc) 29.5 kB
var XMLSerializer = require('xmldom').XMLSerializer , isUrl = require('is-url'); /** * Cf. http://jats.nlm.nih.gov/archiving/tag-library/1.1d1/index.html */ function Jats2Html (ctx, pkg){ this.pkg = pkg || {}; this.ctx = ctx || {}; this.hLevel = 1; //header level: increment for sections... if(this.pkg.article){ this.mainArticle = this.pkg.article.filter(function(x){ return x['@type'] === 'ScholarlyArticle' || x['@type'] === 'MedicalScholarlyArticle'; })[0] || {}; } }; Jats2Html.prototype.parse = function($node){ var html = ''; if($node.nodeType === 3){ html += $node.nodeValue } else if ($node.nodeType === 1){ var tagNameCamelCase = $node.tagName.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); if(tagNameCamelCase in this){ html += this[tagNameCamelCase]($node); } else { var s = new XMLSerializer(); html += '<!--' + s.serializeToString($node) + '-->'; } } return html; }; Jats2Html.prototype._parse = function($node){ var html = ''; for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; html += this.parse($el); } return html; }; Jats2Html.prototype.getAttr = function($node, attrList){ if(!attrList && $node){ attrList = [{name: 'id', value: $node.getAttribute('id')}, {name: 'typeof', value: this.getSectionRdfType($node)}]; } return attrList .filter(function(x) {return x.value;}) .map(function(x){ return x.name + '="'+ x.value + '"'; }) .join(' '); }; Jats2Html.prototype.map = function($node, htmlTagName, attrList){ var html = ''; html += this.openingTag($node, htmlTagName, attrList); html += this._parse($node); html += '</' + htmlTagName + '>'; return html; }; Jats2Html.prototype.openingTag = function($node, htmlTagName, attrList){ var attrs = this.getAttr($node, attrList); var oTag = '<' + htmlTagName; if(attrs){ oTag += ' ' + attrs; } oTag += '>'; return oTag; }; Jats2Html.prototype.selfClosingTag = function($node, htmlTagName, attrList){ var attrs = this.getAttr($node, attrList); var tag = '<' + htmlTagName; if(attrs){ tag += ' ' + attrs; } tag += ' />'; return tag; }; Jats2Html.prototype.getSectionRdfType = function($node){ var rdfTypes = []; var deo = { 'intro': 'http://purl.org/spar/deo/Introduction', 'acknowledgement': 'http://purl.org/spar/deo/Acknowledgements', 'discussion': 'http://salt.semanticauthoring.org/ontologies/sro#Discussion', 'material': 'http://purl.org/spar/deo/Materials', 'method': 'http://purl.org/spar/deo/Methods', 'result': 'http://purl.org/spar/deo/Results', 'conclusion': 'http://salt.semanticauthoring.org/documentation.html#Conclusion' }; //synonyms deo.introduction = deo.intro; Object.keys(deo).forEach(function(key){ deo[key + 's'] = deo[key]; }); var secType = $node.getAttribute('sec-type'); var $title = $node.getElementsByTagName('title')[0]; if(secType){ secType = secType.split('|'); // “sec-type="materials|methods" } else if ($title){ secType = $title.textContent.split(' '); } if(secType){ secType = secType.map(function(x) {return x.trim().toLowerCase()}); secType.forEach(function(t){ if(t in deo){ rdfTypes.push(deo[t]); } }); } return rdfTypes.join(' '); }; //All the tags... Jats2Html.prototype.article = function($node){ var meta = (this.pkg.keywords || []) .map(function(x){ return '<meta property="schema:keyword" content="' + x + '">'; }); ['doi', 'pmid', 'pmcid'].forEach(function(x){ if(this.mainArticle[x]){ meta.push('<meta property="schema:' + x + '" content="' + this.mainArticle[x] + '">'); }; }, this); return [ '<!DOCTYPE html>', '<html typeof="schema:' + (this.mainArticle['@type'] || 'Article' ) + '">', '<head>', '<meta charset=utf-8 />', (this.mainArticle.headline) ? ('<title>' + this.mainArticle.headline + '</title>') :'', meta.join(''), '</head>', '<body>', this.map($node, 'article'), '</body>', '</html>' ].join(''); }; /** * Only abstract * TODO add all the meta info from the pkg */ Jats2Html.prototype.front = function($node){ var innerHtml = this._pkgMeta2Html() || ''; this.hLevel++; var $abstracts = $node.getElementsByTagName('abstract'); if($abstracts && $abstracts.length){ for(var i=0; i<$abstracts.length; i++){ innerHtml += this.parse($abstracts[i]); } } this.hLevel--; var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'typeof', value: 'http://purl.org/spar/doco/FrontMatter'} ]; return (innerHtml)? (this.openingTag($node, 'section', attrList) + innerHtml + '</section>') : ''; }; Jats2Html.prototype._pkgMeta2Html = function(){ var html = ''; if(this.mainArticle.headline){ html += '<h1 property="schema:headline">' + this.mainArticle.headline + '</h1>'; } return html; }; /** * TODO add citations from the pkg */ Jats2Html.prototype.back = function($node){ var innerHtml = '' this.hLevel++; for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; if($el.nodeType === 3){ innerHtml += $el.nodeValue; } else if($el.tagName === 'ref-list') { innerHtml += this.openingTag($el, 'section', [{ name: 'id', value: $el.getAttribute('id'), name: 'typeof', value: 'http://purl.org/spar/doco/Bibliography' }]); innerHtml += this._citations2Html(); innerHtml += '</section>'; } else { innerHtml += this.parse($el); } } this.hLevel--; var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'typeof', value: 'http://purl.org/spar/doco/BackMatter'} ]; return (innerHtml)? (this.openingTag($node, 'section', attrList) + innerHtml + '</section>') : ''; }; Jats2Html.prototype.body = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'property', value: 'schema:articleBody'} ]; return this.map($node, 'main', attrList); }; Jats2Html.prototype.sec = function($node){ var html = ''; this.hLevel++; html += this.openingTag($node, 'section'); for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; if($el.nodeType === 3){ html += $el.nodeValue; } else if($el.tagName === 'label') { continue; } else if($el.tagName === 'title') { html += this.title($el); } else { html += this.parse($el); } } html += '</section>'; this.hLevel--; return html; }; Jats2Html.prototype.p = function($node){ return this.map($node, 'p'); }; Jats2Html.prototype.sup = function($node){ return this.map($node, 'sup'); }; Jats2Html.prototype.sub = function($node){ return this.map($node, 'sub'); }; Jats2Html.prototype.bold = function($node){ return this.map($node, 'strong'); }; Jats2Html.prototype.italic = function($node){ return this.map($node, 'em'); }; Jats2Html.prototype.underline = function($node){ return this.map($node, 'u'); }; Jats2Html.prototype.dispQuote = function($node){ return this.map($node, 'blockquote'); }; Jats2Html.prototype.preformat = function($node){ return this.map($node, 'pre'); }; Jats2Html.prototype.dispFormulaGroup = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.fnGroup = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.fn = function($node){ return this.map($node, 'aside'); }; Jats2Html.prototype.boxedText = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.floatGroup = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.abbrev = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'title', value: $node.getAttribute('alt')} ]; return this.map($node, 'abbr', attrList); }; Jats2Html.prototype.hr = function($node){ return this.selfClosingTag($node, 'hr'); }; Jats2Html.prototype.break = function($node){ return this.selfClosingTag($node, 'br'); }; Jats2Html.prototype.xref = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'href', value: '#' + ($node.getAttribute('rid') || '') }, {name: 'class', value: $node.getAttribute('ref-type')} ]; return this.map($node, 'a', attrList); }; Jats2Html.prototype.extLink = function($node){ var html = ''; var href = $node.getAttribute('xlink:href'); if(href){ href = isUrl(href) ? href: ('#' + href); } var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'href', value: href }, {name: 'title', value: $node.getAttribute('xlink:title') }, {name: 'class', value: $node.getAttribute('ext-link-type')} ]; if($node.childNodes.length && $node.childNodes.length) { html = this.map($node, 'a', attrList); } else { html = this.openingTag($node, 'a', attrList); html += href || ''; html += '</a>'; } return html; }; Jats2Html.prototype.uri = function($node){ var href = $node.getAttribute('xlink:href'); if(!href){ href = ($node.textContent || '').trim(); } href = isUrl(href) ? href: ('#' + href); var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'href', value: href }, {name: 'title', value: $node.getAttribute('xlink:title') }, {name: 'class', value: $node.getAttribute('xlink:type')} ]; return this.map($node, 'a', attrList); }; Jats2Html.prototype.inlineSupplementaryMaterial = function($node){ var href = $node.getAttribute('xlink:href'); if(href){ href = isUrl(href) ? href: ('#' + href); } var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'href', value: href }, {name: 'title', value: $node.getAttribute('xlink:title') }, {name: 'class', value: $node.getAttribute('xlink:type')} ]; return this.map($node, 'a', attrList); }; Jats2Html.prototype.inlineFormula = function($node){ var html = this.openingTag($node, 'span', [ {name: 'id', value: $node.getAttribute('id')}, {name: 'class', value: 'inline-formula'} ]); var $mathMl = $node.getElementsByTagName('mml:math')[0]; var $texMath = $node.getElementsByTagName('tex-math')[0]; var $inlineGraphic = $node.getElementsByTagName('inline-graphic')[0]; if($mathMl){ html += this['mml:math']($mathMl); } else if($texMath){ html += this.texMath($texMath); } else if($inlineGraphic) { html += this.inlineGraphic($inlineGraphic); } else { //probably normal HTML... html += this._parse($node); } html += '</span>'; return html; }; Jats2Html.prototype.dispFormula = function($node){ var html = this.openingTag($node, 'div', [ {name: 'id', value: $node.getAttribute('id')}, {name: 'class', value: 'disp-formula'} ]); for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; if($el.nodeType === 3){ html += $el.nodeValue; } else if($el.tagName === 'label') { html += this.openingTag($el, 'cite'); html += $el.textContent; html += '</cite>'; } else { html += this.parse($el); } } html += '</div>'; return html; }; Jats2Html.prototype.inlineGraphic = function($node){ return this.selfClosingTag($node, 'img', [ {name: 'id', value: $node.getAttribute('id')}, {name: 'class', value: 'inline-graphic'}, {name: 'src', value: this.ctx[$node.getAttribute('xlink:href')]} ]); }; Jats2Html.prototype.graphic = function($node){ return this.selfClosingTag($node, 'img', [ {name: 'id', value: $node.getAttribute('id')}, {name: 'src', value: this.ctx[$node.getAttribute('xlink:href')]} ]); }; Jats2Html.prototype.texMath = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'class', value: 'latex'} ]; return '<pre>' + this.map($node, 'code', attrList) + '</pre>'; }; Jats2Html.prototype['mml:math'] = function($node){ Array.prototype.forEach.call($node.attributes, function(x){ $node.removeAttribute(x.name); }); $node.setAttribute('xmlns', 'http://www.w3.org/1998/Math/MathML'); var s = new XMLSerializer(); var html = s.serializeToString($node); return html.replace(/mml:/g, ''); }; Jats2Html.prototype.chemStruct = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.code = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'class', value: $node.getAttribute('code-type') || $node.getAttribute('language')} ]; return '<pre>' + this.map($node, 'code', attrList) + '</pre>'; }; Jats2Html.prototype.list = function($node){ var listType = $node.getAttribute('list-type'); var tagName; if(listType === 'order' || listType === 'alpha-lower' || listType === 'alpha-upper' || listType === 'roman-lower' || listType === 'roman-upper') { tagName = 'ol'; } else { tagName = 'ul'; } var html = this.openingTag($node, tagName); var $listItems = $node.getElementsByTagName('list-item'); if($listItems && $listItems.length){ for(var i=0; i<$listItems.length; i++){ html += this.openingTag($listItems[i], 'li'); html += this._parse($listItems[i]); html += '</li>'; } } html += '</' + tagName + '>'; return html; }; Jats2Html.prototype.defList = function($node){ var html = this.openingTag($node, 'dl'); var i, j; var $defItems = $node.getElementsByTagName('def-item'); if($defItems && $defItems.length){ for(i=0; i<$defItems.length; i++){ var $terms = $defItems[i].getElementsByTagName('term'); if($terms && $terms.length){ for(j=0; j<$terms.length; j++){ html += this.openingTag($terms[j], 'dt'); html += this._parse($terms[j]); html += '</dt>'; } } var $defs = $defItems[i].getElementsByTagName('def'); if($defs && $defs.length){ for(j=0; j<$defs.length; j++){ html += this.openingTag($defs[j], 'dd'); html += this._parse($defs[j]); html += '</dd>'; } } } } html += '</dl>'; return html; }; /** * helper to get <figcaption> or <caption> * $node is a node containing <label>, <caption> or <table-wrap-foot> */ Jats2Html.prototype._caption = function($node, tagName){ var html = ''; var $label = $node.getElementsByTagName('label')[0]; var $caption = $node.getElementsByTagName('caption')[0]; var $tableWrapFoot = $node.getElementsByTagName('tableWrapFoot')[0]; if($label || $caption || $tableWrapFoot){ html += this.openingTag($caption || $label || $tableWrapFoot, tagName); var $title; if($caption){ $title = $caption.getElementsByTagName('title')[0]; } if($label || $title){ html += '<header>'; if($label){ html += this.openingTag($label, 'cite'); html += this._parse($label) html += '</cite>'; } if($title){ html += this.openingTag($title, 'h3'); html += this._parse($title) html += '</h3>'; } html += '</header>'; } if($caption){ var $ps = $caption.getElementsByTagName('p'); if($ps && $ps.length){ for(var i=0; i<$ps.length; i++){ html += this.p($ps[i]); } } } if($tableWrapFoot){ html += this.tableWrapFoot($tableWrapFoot); } html += '</' + tagName + '>'; } return html; }; Jats2Html.prototype.tableWrapFoot = function($node){ var html = this.openingTag($node, 'footer'); var content = ''; var $label, $title; for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; if($el.nodeType === 3){ content += $el.nodeValue; } else if($el.tagName === 'label') { $label = $el; } else if($el.tagName === 'title') { $title = $el; } else { content += this.parse($el); } } if($label || $title){ html += '<header>'; if($label){ html += this.openingTag($label, 'cite'); html += this._parse($label) html += '</cite>'; } if($title){ html += this.openingTag($title, 'h4'); html += this._parse($title) html += '</h4>'; } html += '</header>'; } html += content; html += '</footer>'; return html; }; /** * only figcaption, <img> <video> or <audio> will be added in JS */ Jats2Html.prototype.fig = function($node){ var html = this.openingTag($node, 'figure'); html += this._caption($node, 'figcaption'); html += '</figure>'; return html; }; Jats2Html.prototype.figGroup = function($node){ var html = this.openingTag($node, 'figure'); html += this._caption($node, 'figcaption'); var $figs = $node.getElementsByTagName('fig'); if($figs && $figs.length){ for(var i=0; i<$figs.length; i++){ html += this.fig($figs[i]); } } html += '</figure>'; return html; }; /** * only caption and <table>, <img> <video> or <audio> will be added in JS */ Jats2Html.prototype.tableWrap = function($node){ var html = this.openingTag($node, 'table'); html += this._caption($node, 'caption'); //also take into account table-wrap-foot var $table = $node.getElementsByTagName('table')[0]; if($table){ html += this.table($node); } html += '</table>'; return html; }; Jats2Html.prototype.tableWrapGroup = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.supplementaryMaterial = function($node){ var html = this.openingTag($node, 'aside'); html += this._caption($node, 'div'); html += '</aside>'; return html; }; Jats2Html.prototype.chemStructWrap = function($node){ var html = this.openingTag($node, 'figure'); html += this._caption($node, 'figcaption'); html += '</figure>'; return html; }; /** * return the innerHTML of $node (table) */ Jats2Html.prototype.table = function($node){ return this._parse($node); }; Jats2Html.prototype.colgroup = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'bgcolor', value: $node.getAttribute('bgcolor')}, {name: 'span', value: $node.getAttribute('span')}, {name: 'width', value: $node.getAttribute('width')} ]; return this.map($node, 'colgroup', attrList); }; Jats2Html.prototype.col = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'bgcolor', value: $node.getAttribute('bgcolor')}, {name: 'span', value: $node.getAttribute('span')} ]; return this.map($node, 'col', attrList); }; Jats2Html.prototype.thead = function($node){ return this.map($node, 'thead'); }; Jats2Html.prototype.tbody = function($node){ return this.map($node, 'tbody'); }; Jats2Html.prototype.tfoot = function($node){ return this.map($node, 'tfoot'); }; Jats2Html.prototype.tr = function($node){ return this.map($node, 'tr'); }; Jats2Html.prototype.th = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'colspan', value: $node.getAttribute('colspan')}, {name: 'headers', value: $node.getAttribute('headers')}, {name: 'rowspan', value: $node.getAttribute('rowspan')} ]; return this.map($node, 'th', attrList); }; Jats2Html.prototype.td = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'colspan', value: $node.getAttribute('colspan')}, {name: 'headers', value: $node.getAttribute('headers')}, {name: 'rowspan', value: $node.getAttribute('rowspan')} ]; return this.map($node, 'td', attrList); }; Jats2Html.prototype.ack = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'typeof', value: 'http://purl.org/spar/deo/Acknowledgements'} ]; return this.map($node, 'section', attrList); }; //TODO fix RDFa / structured abstract Jats2Html.prototype.abstract = function($node){ var attrList = [ {name: 'id', value: $node.getAttribute('id')}, {name: 'property', value: 'schema:abstract'}, {name: 'typeof', value: 'schema:Abstract'} ]; var html = this.openingTag($node, 'section', attrList); //easy cases: basic unstructured abstract with optional <p> and <title> (and that only) if($node.childNodes.length <= 2 && Array.prototype.every.call($node.childNodes, function($el){ return $el.tagName === 'p' || $el.tagName === 'title'; }) ){ Array.prototype.forEach.call($node.childNodes, function($el){ html += this.map($el, ($el.tagName === 'p')? 'p': ('h' + this.hLevel) , [ {name: 'id', value: $el.getAttribute('id')}, {name: 'property', value: ($el.tagName === 'p')? 'schema:abstractBody': 'schema:headline'} ]); }.bind(this)); } else { var isStructured = Array.prototype.some.call($node.childNodes, function($el){ return $el.tagName === 'sec'; }); if(!isStructured){ //add a wrapper div html += '<div property="schema:abstractBody">'; } for(var i=0; i<$node.childNodes.length; i++){ var $el = $node.childNodes[i]; if($el.nodeType === 3){ html += $el.nodeValue; } else if($el.tagName === 'sec') { html += this._abstractPart($el); } else { html += this.parse($el); } } if(!isStructured){ html += '</div>'; } } html += '</section>'; return html; }; Jats2Html.prototype._abstractPart = function($sec){ var attrList = [ {name: 'id', value: $sec.getAttribute('id')}, {name: 'typeof', value: 'schema:Abstract'}, {name: 'property', value: 'schema:hasPart'} ]; var html = this.openingTag($sec, 'section', attrList); this.hLevel++; //easy case: 1 <title> and or 1 <p> only" if($sec.childNodes && $sec.childNodes.length <= 2 && Array.prototype.every.call($sec.childNodes, function($el){ return $el.tagName === 'p' || $el.tagName === 'title'; }) ){ Array.prototype.forEach.call($sec.childNodes, function($el){ html += this.map($el, ($el.tagName === 'p')? 'p': ('h' + this.hLevel) , [ {name: 'id', value: $el.getAttribute('id')}, {name: 'property', value: ($el.tagName === 'p')? 'schema:abstractBody': 'schema:headline'} ]); }.bind(this)); } else { //more tricky case, we mark the title (if any and if first child) as schema:headline and we wrap all that follows in a <div property="abstractBody"> for(var i=0; i<$sec.childNodes.length; i++){ var $el = $sec.childNodes[i]; if($el.nodeType === 3){ html += $el.nodeValue; } else if($el.tagName === 'title') { html += this.map($el, 'h' + this.hLevel, [ {name: 'id', value: $el.getAttribute('id')}, {name: 'property', value: 'schema:headline'} ]); //open wrapper div for abstractBody html += '<div property="abstractBody">'; } else { html += this.parse($el); } } html += '</div>'; // close wrapper div for abstractBody } this.hLevel--; html += '</section>'; return html; }; /** * mapping that should rarely be called (these elements are handled by higher level tags) * TODO improve */ Jats2Html.prototype.title = function($node){ return this.map($node, 'h' + this.hLevel); }; Jats2Html.prototype.label = function($node){ return this.map($node, 'span'); }; Jats2Html.prototype.caption = function($node){ return this.map($node, 'div'); }; Jats2Html.prototype.glossary = function($node){ return this.map($node, 'section'); }; /** * id: the id of <ref-list> */ Jats2Html.prototype._citations2Html = function(){ var html = (this.mainArticle.citation || []).map(function(ref){ var li = ''; li += this.openingTag(null, 'li', [ {name: 'id', value: ref.name}, {name: 'typeof', value: (ref['@type'])? ('schema:' + ref['@type']) : undefined}, {name: 'property', value: 'schema:citation'}, ]); var inlines = []; //all the inlines element will be join with ' ' //label if(ref.alternateName){ inlines.push('<span property="schema:alternateName">' + ref.alternateName + '</span>'); } inlines.push( [ref.author].concat(ref.contributor) .filter(function(p){ return p; }) .map(function(p){ var html = '<span typeof="schema:Person">'; if(p.familyName){ html += '<span property="schema:familyName">' + p.familyName + '</span>'; } if(p.givenName){ if(p.familyName) html += ' '; html += '<span property="schema:givenName">' + p.givenName + '</span>'; } html += '</span>'; return html; }) .join(', ') ); if(ref.unnamedContributors){ inlines.push('<em property="pkg:unnamedContributors" content="true">et al.</em>'); } if(ref.datePublished){ inlines.push('<span property="schema:datePublished" content="'+ ref.datePublished +'">(' + (new Date(ref.datePublished)).getFullYear() + ')</span>'); } if(ref.headline){ inlines.push('<span property="schema:headline">' + ref.headline + '</span>'); } // issue, volume and periodical, we want smtg like: // <!-- Archives of internal medicine 169 (4) :335-341 --> // <div vocab="http://schema.org/" typeof="MedicalScholarlyArticle"> // <span property="isPartOf" typeof="PublicationIssue"> // <span property="isPartOf" typeof="PublicationVolume"> // <span property="isPartOf" typeof="Periodical"> // <span property="alternateName">Arch. Intern. Med.</span> // <meta property="name" content="Archives of internal medicine"/> // </span> // <span property="volumeNumber">169</span> // </span> // (<span property="issueNumber">4</span>) // </span> // :<span property="pageStart">335</span>-<span property="pageEnd">341</span> // </div> var periodicalHtml, volumeHtml, issueHtml, pagesHtml; if(ref.isPartOf){ var periodical = _getPartOf(ref.isPartOf, 'Periodical'); var volume = _getPartOf(ref.isPartOf, 'PublicationVolume'); var issue = _getPartOf(ref.isPartOf, 'PublicationIssue'); if(periodical && (periodical.name || periodical.alternateName)){ periodicalHtml = '<span property="isPartOf" typeof="Periodical">'; if(periodical.alternateName){ periodicalHtml += '<span property="alternateName">' + periodical.alternateName + '</span>'; if(periodical.name){ periodicalHtml += '<meta property="name" content="' + periodical.name + '" />'; } } else { periodicalHtml += '<span property="name">' + periodical.name + '</span>'; } periodicalHtml += '</span>'; } if(volume && volume.volumeNumber !== undefined){ volumeHtml = '<span property="isPartOf" typeof="PublicationVolume">'; if(periodicalHtml){ volumeHtml += periodicalHtml + ' '; } volumeHtml += '<span property="schema:volumeNumber">' + volume.volumeNumber + '</span>'; volumeHtml += '</span>'; } if(issue && issue.issueNumber !== undefined){ issueHtml = '<span property="isPartOf" typeof="PublicationIssue">'; issueHtml += volumeHtml || periodicalHtml || ''; issueHtml += '(<span property="bibo:issue">' + issue.issueNumber + '</span>)'; } } if(ref.pagination || ref.pageStart !== undefined){ pagesHtml = (volumeHtml || issueHtml) ? ':' : ((periodicalHtml) ? ' ': ''); if(ref.pagination){ pagesHtml += '<span property="schema:pagination">' + ref.pagination + '</span>'; } else if(ref.pageStart !== undefined){ pagesHtml += '<span property="schema:pageStart">' + ref.pageStart + '</span>' + ( (ref.pageEnd !== undefined)? ('-<span property="schema:pageEnd">' + ref.pageEnd + '</span>') : ''); } } inlines.push((issueHtml || volumeHtml || periodicalHtml || '') + (pagesHtml || '') ); li += inlines.join(' '); li += '. '; if(ref.doi || ref.pmid){ li += '<ul>'; if(ref.doi){ li+= '<li><a property="bibo:doi" href="http://dx.doi.org/' + ref.doi + '">doi</a></li>'; } if(ref.pmid){ li+= '<li><a property="bibo:pmid" href="http://www.ncbi.nlm.nih.gov/pubmed/' + ref.pmid + '">PubMed</a></li>'; } li += '</ul>'; } li += '</li>'; return li; }, this).join(''); return this.openingTag(null, 'ul', [{name: 'typeof', value:'http://purl.org/spar/doco/BibliographicReferenceList'}]) + html + '</ul>'; }; function _getPartOf(isPartOf, type){ if(!isPartOf) return; var part = isPartOf; while(part['@type'] !== type){ if(part.isPartOf){ part = part.isPartOf; } else { part = undefined; break; } } return part; }; module.exports = Jats2Html;