blob: 4890749ad7243398bcaaa9a087d5dde5dc1f6e9c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import angular from 'angular';
import marked from 'marked';
const MODULE_NAME = 'br.utils.md-helper';
angular.module(MODULE_NAME, [])
.factory("mdHelper", mdHelperProvider)
.directive('mdField', [ mdFieldDirective])
.directive('mdFirstLine', [ mdFirstLineDirective])
.directive('mdIfOneline', [ mdIfOnelineDirective])
.directive('mdIfMultiline', [mdIfMultilineDirective]);
export default MODULE_NAME;
// displays markdown, as one-line or multi-line depending on the data
export function mdFieldDirective() {
return {
restrict: 'E',
scope: {
data: '<',
rawData: '<',
rawItem: '<',
},
controller: ['$scope', populateData],
template: `
<div>
<md-if-oneline data="data"></md-if-oneline>
<md-if-multiline data="data"></md-if-multiline>
</div>
`,
};
}
// prints out one line of data -- in future could use markdown formatting, but currently does not
export function mdFirstLineDirective() {
return {
restrict: 'E',
scope: {
data: '<',
rawData: '<',
rawItem: '<',
},
controller: ['$scope', populateData],
template: `
<span>{{::data.oneline}}</span>
`,
};
}
// prints out full, formatted, _if_ it is one line of data
export function mdIfOnelineDirective() {
return {
restrict: 'E',
scope: {
data: '<',
rawData: '<',
rawItem: '<',
},
controller: ['$scope', populateData],
template: `
<div ng-if="data.isNonMultiline">
<p ng-if="data.unformatted">{{data.unformatted}}</p>
<div ng-if="data.markdownFormatted" ng-bind-html="data.markdownFormatted"></div>
</div>
`,
};
}
// prints out all the data, formatted, if multiline
export function mdIfMultilineDirective() {
return {
restrict: 'E',
scope: {
data: '<',
rawData: '<',
rawItem: '<',
},
controller: ['$scope', populateData],
// for multiline, collapse margin from children eg an <h1> first element, inserting then removing a 24px margin
template: `
<div ng-if="data.isMultiline">
<pre ng-if="data.unformatted">{{data.unformatted}}</pre>
<div ng-if="data.markdownFormatted" style="margin-top: -24px;"><div style="margin-top: 24px;" ng-bind-html="data.markdownFormatted"></div></div>
</div>
`,
};
}
function nameFieldValues(src) {
src = src || {};
return ['symbolicName', 'displayName', 'typeName', 'name'].map(x => src[x]);
}
function populateData($scope) {
if (!$scope.data) {
if (!$scope.rawData && $scope.rawItem) {
$scope.rawData = $scope.rawItem.description;
}
$scope.data = analyze($scope.rawData, nameFieldValues($scope.rawItem));
}
}
export function analyzeDescription(input) {
input = input || {};
return analyze(input.description, nameFieldValues(input));
}
export function analyze(field, names) {
let result = {
isPresent: !!field,
};
result.isMultiline = !!(result.isPresent && (field.trim().match(/^#+($| )/) || field.split('\n', 5)>5));
result.isNonMultiline = result.isPresent && !result.isMultiline;
if (result.isPresent) {
try {
result.markdownFormatted = marked(field);
} catch (e) {
console.log("could not convert markdown; treading as unformatted", e);
// not markdown
result.unformatted = field;
}
}
result.oneline = oneline(field, names);
return result;
}
function containsAny(line, words) {
if (!words) return false;
return words.filter(w => w && line.indexOf(w)>=0);
}
export function oneline(field, names) {
if (!field) {
return null;
}
if (field.trim().match(/^#+($| )/)) {
// looks like markdown; skip line if it's a title
let inputStripped = field.trim().substring(1);
let line1 = inputStripped.split('\n', 1)[0].trim();
if (!line1 || (containsAny(line1, names) && line1.length<100)) {
// probably a summary eg "About FooEntity" -- ignore
inputStripped = /\n((.*)(\n.*)*)/.exec(inputStripped)[1]
if (!inputStripped) return null;
return oneline(inputStripped, names);
}
// otherwise use default behaviour
field = line1;
}
let dStrippedP = field.trim().split('\n', 2);
let d = dStrippedP[0];
if (d.length > 200) {
// if very long then truncate and return...
return d.substring(0,197)+"...";
} else {
if (dStrippedP[1] !== undefined) {
d += " ...";
}
return d;
}
}
function mdHelperProvider() {
return {
analyze,
analyzeDescription,
}
}