5 angular.module('egPrintLabels',
6 ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
8 .config(function ($routeProvider, $locationProvider, $compileProvider) {
9 $locationProvider.html5Mode(true);
10 $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|mailto|blob):/); // grid export
13 delay: ['egStartup', function (egStartup) { return egStartup.go(); }]
16 $routeProvider.when('/cat/printlabels/:dataKey', {
17 templateUrl: './cat/printlabels/t_view',
18 controller: 'LabelCtrl',
29 copies: [], // copy barcode search results
30 index: 0 // search grid index
36 acp: ['call_number', 'location', 'status', 'location', 'floating', 'circ_modifier', 'age_protect'],
37 acn: ['record', 'prefix', 'suffix'],
38 acp: ['call_number', 'location', 'status', 'location', 'floating', 'circ_modifier', 'age_protect', 'circ_lib'],
39 acn: ['record', 'prefix', 'suffix', 'owning_lib'],
40 bre: ['simple_record', 'creator', 'editor']
43 // avoid fleshing MARC on the bre
44 // note: don't add simple_record.. not sure why
45 bre: ['id', 'tcn_value', 'creator', 'editor'],
49 // resolved with the last received copy
50 service.fetch = function (barcode, id, noListDupes) {
54 promise = egCore.pcrud.search('acp',
55 { barcode: barcode, deleted: 'f' }, service.flesh);
57 promise = egCore.pcrud.retrieve('acp', id, service.flesh);
62 function () { return lastRes },
65 // notify reads the stream of copies, one at a time.
70 // use the existing copy if possible
71 flatCopy = service.copies.filter(
72 function (c) { return c.id == copy.id() })[0];
76 flatCopy = egCore.idl.toHash(copy, true);
77 flatCopy.index = service.index++;
78 service.copies.unshift(flatCopy);
95 .controller('LabelCtrl',
96 ['$scope', '$q', '$window', '$routeParams', '$location', '$timeout', 'egCore', 'egNet', 'ngToast', 'itemSvc', 'labelOutputRowsFilter',
97 function ($scope, $q, $window, $routeParams, $location, $timeout, egCore, egNet, ngToast, itemSvc, labelOutputRowsFilter) {
99 var dataKey = $routeParams.dataKey;
100 console.debug('dataKey: ' + dataKey);
103 template_name: 'item_label',
105 template_context: 'default'
108 var toolbox_settings = {
111 { label: "Continuous", value: "continuous" },
112 { label: "Sheet", value: "sheet" },
114 selected: "continuous"
122 { label: "Spine Label", value: "spine-only" },
123 { label: "Pocket Label", value: "spine-pocket" }
125 selected: "spine-pocket"
128 column_class: ["spine", "pocket"],
142 top: { size: 0, label: "Top" },
143 left: { size: 0, label: "Left" },
145 space_between_labels: {
146 horizontal: { size: 0, label: "Horizontal" },
147 vertical: { size: 0, label: "Vertical" }
156 if (dataKey && dataKey.length > 0) {
160 'open-ils.actor.anon_cache.get_value',
161 dataKey, 'print-labels-these-copies'
162 ).then(function (data) {
166 $scope.preview_scope = {
169 , 'toolbox_settings': JSON.parse(JSON.stringify(toolbox_settings))
170 , 'get_cn_for': function (copy) {
171 var key = $scope.rendered_cn_key_by_copy_id[copy.id];
173 var manual_cn = $scope.rendered_call_number_set[key];
174 if (manual_cn && manual_cn.value) {
175 return manual_cn.value;
183 , 'get_bib_for': function (copy) {
184 return $scope.record_details[copy['call_number.record.id']];
186 , 'get_cn_prefix': function (copy) {
187 return copy['call_number.prefix.label'];
189 , 'get_cn_suffix': function (copy) {
190 return copy['call_number.suffix.label'];
192 , 'get_location_prefix': function (copy) {
193 return copy['location.label_prefix'];
195 , 'get_location_suffix': function (copy) {
196 return copy['location.label_suffix'];
198 , 'get_cn_and_location_prefix': function (copy, separator) {
199 var acpl_prefix = copy['location.label_prefix'] || '';
200 var cn_prefix = copy['call_number.prefix.label'] || '';
201 var prefix = acpl_prefix + ' ' + cn_prefix;
202 prefix = prefix.trim();
203 if (separator && prefix != '') { prefix += separator; }
206 , 'get_cn_and_location_suffix': function (copy, separator) {
207 var acpl_suffix = copy['location.label_suffix'] || '';
208 var cn_suffix = copy['call_number.suffix.label'] || '';
209 var suffix = cn_suffix + ' ' + acpl_suffix;
210 suffix = suffix.trim();
211 if (separator && suffix != '') { suffix = separator + suffix; }
214 , 'valid_print_label_start_column': function () {
215 return !angular.isNumber(toolbox_settings.page.dimensions.columns) || !angular.isNumber(toolbox_settings.page.start_position.column) ? false : (toolbox_settings.page.start_position.column <= toolbox_settings.page.dimensions.columns);
217 , 'valid_print_label_start_row': function () {
218 return !angular.isNumber(toolbox_settings.page.dimensions.rows) || !angular.isNumber(toolbox_settings.page.start_position.row) ? false : (toolbox_settings.page.start_position.row <= toolbox_settings.page.dimensions.rows);
221 $scope.record_details = {};
222 $scope.org_unit_settings = {};
225 $scope.org_unit_setting_list = [
226 'webstaff.cat.label.font.family'
227 , 'webstaff.cat.label.font.size'
228 , 'webstaff.cat.label.font.weight'
229 , 'webstaff.cat.label.inline_css'
230 , 'webstaff.cat.label.left_label.height'
231 , 'webstaff.cat.label.left_label.left_margin'
232 , 'webstaff.cat.label.left_label.width'
233 , 'webstaff.cat.label.right_label.height'
234 , 'webstaff.cat.label.right_label.left_margin'
235 , 'webstaff.cat.label.right_label.width'
236 , 'webstaff.cat.label.call_number_wrap_filter_height'
237 , 'webstaff.cat.label.call_number_wrap_filter_width'
241 egCore.pcrud.search('coust', { name: $scope.org_unit_setting_list }).then(
245 $scope.org_unit_settings[yaous.name()] = egCore.idl.toHash(yaous, true);
251 egCore.org.settings($scope.org_unit_setting_list).then(function (res) {
252 $scope.preview_scope.settings = res;
253 egCore.hatch.getItem('cat.printlabels.last_settings').then(function (last_settings) {
255 for (s in last_settings) {
256 $scope.preview_scope.settings[s] = last_settings[s];
260 egCore.hatch.getItem('cat.printlabels.last_toolbox_settings').then(function (last_toolbox_settings) {
261 if (last_toolbox_settings) {
262 $scope.preview_scope.toolbox_settings = JSON.parse(JSON.stringify(last_toolbox_settings));
268 angular.forEach(data.copies, function (copy) {
270 itemSvc.fetch(null, copy).then(function (res) {
271 var flat_copy = egCore.idl.toHash(res.copy, true);
272 $scope.preview_scope.copies.push(flat_copy);
273 $scope.record_details[flat_copy['call_number.record.id']] = 1;
278 $q.all(promises).then(function () {
281 angular.forEach($scope.record_details, function (el, k, obj) {
285 'open-ils.search.biblio.record.mods_slim.retrieve.authoritative',
287 ).then(function (data) {
288 obj[k] = egCore.idl.toHash(data, true);
293 $q.all(promises2).then(function () {
294 // today, staff, current_location, etc.
295 egCore.print.fleshPrintScope($scope.preview_scope);
296 $scope.template_changed(); // load the default
297 $scope.rebuild_cn_set();
302 ngToast.danger(egCore.strings.KEY_EXPIRED);
309 $scope.checkForToolboxCustomizations = function (tText, redraw) {
310 var re = /eg\_plt\_(\d+)/;
311 redraw ? $scope.redraw_label_table() : false;
312 return re.test(tText);
315 $scope.fetchTemplates = function (set_default) {
316 return egCore.hatch.getItem('cat.printlabels.templates').then(function (t) {
318 $scope.templates = t;
319 $scope.template_name_list = Object.keys(t);
321 egCore.hatch.getItem('cat.printlabels.default_template').then(function (d) {
322 if ($scope.template_name_list.indexOf(d, 0) > -1) {
323 $scope.template_name = d;
330 $scope.fetchTemplates(true);
332 $scope.applyTemplate = function (n) {
333 $scope.print.cn_template_content = $scope.templates[n].cn_content;
334 $scope.print.template_content = $scope.templates[n].content;
335 $scope.print.template_context = $scope.templates[n].context;
336 for (var s in $scope.templates[n].settings) {
337 $scope.preview_scope.settings[s] = $scope.templates[n].settings[s];
339 if ($scope.templates[n].toolbox_settings) {
340 $scope.preview_scope.toolbox_settings = JSON.parse(JSON.stringify($scope.templates[n].toolbox_settings));
342 egCore.hatch.setItem('cat.printlabels.default_template', n);
343 $scope.save_locally();
346 $scope.deleteTemplate = function (n) {
348 delete $scope.templates[n]
349 $scope.template_name_list = Object.keys($scope.templates);
350 $scope.template_name = '';
351 egCore.hatch.setItem('cat.printlabels.templates', $scope.templates);
352 $scope.fetchTemplates();
353 ngToast.create(egCore.strings.PRINT_LABEL_TEMPLATE_SUCCESS_DELETE);
354 egCore.hatch.getItem('cat.printlabels.default_template').then(function (d) {
356 egCore.hatch.removeItem('cat.printlabels.default_template');
362 $scope.saveTemplate = function (n) {
365 $scope.templates[n] = {
366 content: $scope.print.template_content
367 , context: $scope.print.template_context
368 , cn_content: $scope.print.cn_template_content
369 , settings: JSON.parse(JSON.stringify($scope.preview_scope.settings))
370 , toolbox_settings: JSON.parse(JSON.stringify($scope.preview_scope.toolbox_settings))
372 $scope.template_name_list = Object.keys($scope.templates);
374 egCore.hatch.setItem('cat.printlabels.templates', $scope.templates);
375 $scope.fetchTemplates();
377 $scope.dirty = false;
379 // save all templates, as we might do after an import
380 egCore.hatch.setItem('cat.printlabels.templates', $scope.templates);
381 $scope.fetchTemplates();
383 ngToast.create(egCore.strings.PRINT_LABEL_TEMPLATE_SUCCESS_SAVE);
386 $scope.templates = {};
387 $scope.imported_templates = { data: '' };
388 $scope.template_name = '';
389 $scope.template_name_list = [];
391 $scope.print_labels = function () {
392 return egCore.print.print({
393 context: $scope.print.template_context,
394 template: $scope.print.template_name,
395 scope: $scope.preview_scope,
399 $scope.template_changed = function () {
400 $scope.print.load_failed = false;
401 egCore.print.getPrintTemplate('item_label')
404 $scope.print.template_content = html;
405 $scope.checkForToolboxCustomizations(html, true);
408 $scope.print.template_content = '';
409 $scope.print.load_failed = true;
412 egCore.print.getPrintTemplateContext('item_label')
413 .then(function (template_context) {
414 $scope.print.template_context = template_context;
416 egCore.print.getPrintTemplate('item_label_cn')
419 $scope.print.cn_template_content = html;
422 $scope.print.cn_template_content = '';
423 $scope.print.load_failed = true;
426 egCore.hatch.getItem('cat.printlabels.last_settings').then(function (s) {
428 $scope.preview_scope.settings = JSON.parse(JSON.stringify(s));
431 egCore.hatch.getItem('cat.printlabels.last_toolbox_settings').then(function (t) {
433 $scope.preview_scope.toolbox_settings = JSON.parse(JSON.stringify(t));
439 $scope.reset_to_default = function () {
440 egCore.print.removePrintTemplate(
443 egCore.print.removePrintTemplateContext(
446 egCore.print.removePrintTemplate(
449 egCore.hatch.removeItem('cat.printlabels.last_settings');
450 egCore.hatch.removeItem('cat.printlabels.last_toolbox_settings');
451 for (s in $scope.preview_scope.settings) {
452 $scope.preview_scope.settings[s] = undefined;
454 $scope.preview_scope.toolbox_settings = JSON.parse(JSON.stringify(toolbox_settings));
456 egCore.org.settings($scope.org_unit_setting_list).then(function (res) {
457 $scope.preview_scope.settings = res;
460 $scope.template_changed();
463 $scope.save_locally = function () {
464 egCore.print.storePrintTemplate(
466 $scope.print.template_content
468 egCore.print.storePrintTemplateContext(
470 $scope.print.template_context
472 egCore.print.storePrintTemplate(
474 $scope.print.cn_template_content
476 egCore.hatch.setItem('cat.printlabels.last_settings', JSON.parse(JSON.stringify($scope.preview_scope.settings)));
477 egCore.hatch.setItem('cat.printlabels.last_toolbox_settings', JSON.parse(JSON.stringify($scope.preview_scope.toolbox_settings)));
480 $scope.imported_print_templates = { data: '' };
481 $scope.$watch('imported_templates.data', function (newVal, oldVal) {
482 if (newVal && newVal != oldVal) {
484 var data = JSON.parse(newVal);
485 angular.forEach(data, function (el, k) {
486 $scope.templates[k] = {
488 , context: el.context
489 , cn_content: el.cn_content
490 , settings: JSON.parse(JSON.stringify(el.settings))
492 if (el.toolbox_settings) {
493 $scope.templates[k].toolbox_settings = JSON.parse(JSON.stringify(el.toolbox_settings));
496 $scope.saveTemplate();
497 $scope.template_changed(); // refresh
498 ngToast.create(egCore.strings.PRINT_TEMPLATES_SUCCESS_IMPORT);
500 ngToast.warning(egCore.strings.PRINT_TEMPLATES_FAIL_IMPORT);
505 $scope.rendered_call_number_set = {};
506 $scope.rendered_cn_key_by_copy_id = {};
507 $scope.rebuild_cn_set = function () {
508 $timeout(function () {
509 $scope.rendered_call_number_set = {};
510 $scope.rendered_cn_key_by_copy_id = {};
511 for (var i = 0; i < $scope.preview_scope.copies.length; i++) {
512 var copy = $scope.preview_scope.copies[i];
513 var rendered_cn = document.getElementById('cn_for_copy_' + copy.id);
514 if (rendered_cn && rendered_cn.textContent) {
515 var key = rendered_cn.textContent;
516 if (typeof $scope.rendered_call_number_set[key] == 'undefined') {
517 $scope.rendered_call_number_set[key] = {
521 $scope.rendered_cn_key_by_copy_id[copy.id] = key;
524 $scope.preview_scope.tickle = Date() + ' ' + Math.random();
528 $scope.redraw_label_table = function () {
529 if ($scope.print_label_form.$valid && $scope.print.template_content && $scope.preview_scope) {
530 $scope.preview_scope.label_output_copies = labelOutputRowsFilter($scope.preview_scope.copies, $scope.preview_scope.toolbox_settings);
531 var d = new Date().getTime().toString();
532 var html = $scope.print.template_content;
533 if ($scope.checkForToolboxCustomizations(html)) {
534 html = html.replace(/eg\_plt\_\d+/, "eg_plt_" + d);
535 $scope.print.template_content = html;
537 var table = "<table id=\"eg_plt_" + d + "_{{$index}}\" eg-print-label-table style=\"border-collapse: collapse; border: 0 solid transparent; border-spacing: 0; margin: {{$index === 0 ? toolbox_settings.page.margins.top.size : 0}} 0 0 0;\" class=\"custom-label-table{{$index % toolbox_settings.page.dimensions.rows === 0 && $index > 0 && toolbox_settings.feed_option.selected === 'sheet' ? ' page-break' : ''}}\" ng-init=\"parentIndex = $index\" ng-repeat=\"row in label_output_copies\">\n";
539 table += "<td style=\"border: 0 solid transparent; padding: {{parentIndex % toolbox_settings.page.dimensions.rows === 0 && toolbox_settings.feed_option.selected === 'sheet' && parentIndex > 0 ? toolbox_settings.page.space_between_labels.vertical.size : parentIndex > 0 ? toolbox_settings.page.space_between_labels.vertical.size : 0}} 0 0 {{$index === 0 ? toolbox_settings.page.margins.left.size : col.styl ? col.styl : toolbox_settings.page.space_between_labels.horizontal.size}};\" ng-repeat=\"col in row.columns\">\n";
540 table += "<pre class=\"{{col.cls}}\" style=\"border: none; margin-bottom: 0; margin-top: 0; overflow: hidden;\" ng-if=\"col.cls === 'spine'\">\n";
541 table += "{{col.c ? get_cn_for(col.c) : ''}}";
543 table += "<pre class=\"{{col.cls}}{{parentIndex % toolbox_settings.page.dimensions.rows === 0 && parentIndex > 0 && toolbox_settings.feed_option.selected === 'sheet' ? ' page-break' : ''}}\" style=\"border: none; margin-bottom: 0; margin-top: 0; overflow: hidden;\" ng-if=\"col.cls === 'pocket'\">\n";
544 table += "{{col.c ? col.c.barcode : ''}}\n";
545 table += "{{col.c ? col.c['call_number.label'] : ''}}\n";
546 table += "{{col.c ? get_bib_for(col.c).author : ''}}\n";
547 table += "{{col.c ? (get_bib_for(col.c).title | wrap:28:'once':' ') : ''}}\n";
552 var comments = html.match(/\<\!\-\-(?:(?!\-\-\>)(?:.|\s))*\-\-\>\s*/g);
553 html = html.replace(/\<\!\-\-(?:(?!\-\-\>)(?:.|\s))*\-\-\>\s*/g, '');
554 var style = html.match(/\<style[^\>]*\>(?:(?!\<\/style\>)(?:.|\s))*\<\/style\>\s*/gi);
555 var output = (comments ? comments.join("\n") : "") + (style ? style.join("\n") : "") + table;
556 output = output.replace(/\n+/, "\n");
557 $scope.print.template_content = output;
562 $scope.$watch('print.cn_template_content', function (newVal, oldVal) {
563 if (newVal && newVal != oldVal) {
564 $scope.rebuild_cn_set();
568 $scope.$watch("preview_scope.settings['webstaff.cat.label.call_number_wrap_filter_height']", function (newVal, oldVal) {
569 if (newVal && newVal != oldVal) {
570 $scope.rebuild_cn_set();
574 $scope.$watch("preview_scope.settings['webstaff.cat.label.call_number_wrap_filter_width']", function (newVal, oldVal) {
575 if (newVal && newVal != oldVal) {
576 $scope.rebuild_cn_set();
580 $scope.$watchGroup(['preview_scope.toolbox_settings.page.margins.top.size', 'preview_scope.toolbox_settings.page.margins.left.size', 'preview_scope.toolbox_settings.page.dimensions.rows', 'preview_scope.toolbox_settings.page.dimensions.columns', 'preview_scope.toolbox_settings.page.space_between_labels.horizontal.size', 'preview_scope.toolbox_settings.page.space_between_labels.vertical.size', 'preview_scope.toolbox_settings.page.start_position.row', 'preview_scope.toolbox_settings.page.start_position.column', 'preview_scope.toolbox_settings.page.label.gap.size'], function (newVal, oldVal) {
581 if (newVal && newVal != oldVal && $scope.preview_scope.label_output_copies) {
582 $scope.redraw_label_table();
586 $scope.$watch("preview_scope.toolbox_settings.mode.selected", function (newVal, oldVal) {
587 if (newVal && newVal != oldVal && $scope.preview_scope) {
588 var ts_p = $scope.preview_scope.toolbox_settings.page;
589 if (ts_p.label.set.size === 1) {
590 if (newVal === "spine-pocket") {
591 ts_p.column_class = ["spine", "pocket"];
592 ts_p.label.set.size = 2;
594 ts_p.column_class = ["spine"];
597 if (newVal === "spine-only") {
598 for (var i = 0; i < ts_p.label.set.size; i++) {
599 ts_p.column_class[i] = "spine";
602 ts_p.label.set.size === 2 ? ts_p.column_class = ["spine", "pocket"] : false;
605 $scope.redraw_label_table();
609 $scope.$watch("preview_scope.toolbox_settings.page.label.set.size", function (newVal, oldVal) {
610 if (newVal && newVal != oldVal && oldVal) {
611 var ts_p = $scope.preview_scope.toolbox_settings.page;
612 if (angular.isNumber(newVal)) {
613 while (ts_p.column_class.length > ts_p.label.set.size) {
614 ts_p.column_class.splice((ts_p.column_class.length - 1), 1);
616 while (ts_p.column_class.length < ts_p.label.set.size) {
617 ts_p.column_class.push("spine");
623 $scope.$watch('print.cn_template_content', function (newVal, oldVal) {
624 if (newVal && newVal != oldVal) {
625 $scope.rebuild_cn_set();
629 $scope.$watch("preview_scope.settings['webstaff.cat.label.call_number_wrap_filter_height']", function (newVal, oldVal) {
630 if (newVal && newVal != oldVal) {
631 $scope.rebuild_cn_set();
635 $scope.$watch("preview_scope.settings['webstaff.cat.label.call_number_wrap_filter_width']", function (newVal, oldVal) {
636 if (newVal && newVal != oldVal) {
637 $scope.rebuild_cn_set();
641 $scope.current_tab = 'call_numbers';
642 $scope.set_tab = function (tab) {
643 $scope.current_tab = tab;
648 .directive("egPrintLabelColumnBounds", function () {
650 link: function (scope, element, attr, ctrl) {
651 function withinBounds(v) {
652 scope.$watch("preview_scope.toolbox_settings.page.dimensions.columns", function (newVal, oldVal) {
653 ctrl.$setValidity("egWithinPrintColumnBounds", scope.preview_scope.valid_print_label_start_column())
657 ctrl.$parsers.push(withinBounds);
658 ctrl.$formatters.push(withinBounds);
664 .directive("egPrintLabelRowBounds", function () {
666 link: function (scope, element, attr, ctrl) {
667 function withinBounds(v) {
668 scope.$watch("preview_scope.toolbox_settings.page.dimensions.rows", function (newVal, oldVal) {
669 ctrl.$setValidity("egWithinPrintRowBounds", scope.preview_scope.valid_print_label_start_row());
673 ctrl.$parsers.push(withinBounds);
674 ctrl.$formatters.push(withinBounds);
680 .directive("egPrintLabelValidCss", function () {
683 link: function (scope, element, attr, ctrl) {
684 function floatValidation(v) {
685 ctrl.$setValidity("isFloat", v.toString().match(/^\-*(?:^0$|(?:\d+)(?:\.\d{1,})*([a-z]{2}))$/) ? true : false);
688 ctrl.$parsers.push(floatValidation);
693 .directive("egPrintLabelValidInt", function () {
696 link: function (scope, element, attr, ctrl) {
697 function intValidation(v) {
698 ctrl.$setValidity("isInteger", v.toString().match(/^\d+$/));
701 ctrl.$parsers.push(intValidation);
706 .directive('egPrintTemplateOutput', ['$compile', function ($compile) {
707 return function (scope, element, attrs) {
710 return scope.$eval(attrs.content);
713 // create an isolate scope and copy the print context
714 // data into the new scope.
715 // TODO: see also print security concerns in egHatch
716 var result = element.html(value);
717 var context = scope.$eval(attrs.context);
718 var print_scope = scope.$new(true);
719 angular.forEach(context, function (val, key) {
720 print_scope[key] = val;
722 $compile(element.contents())(print_scope);
728 .filter('cn_wrap', function () {
729 return function (input, w, h, wrap_type) {
731 var prefix = input[0];
732 var callnum = input[1];
733 var suffix = input[2];
738 /* handle spine labels differently if using LC */
739 if (wrap_type == 'lc' || wrap_type == 3) {
740 /* Establish a pattern where every return value should be isolated on its own line
741 on the spine label: subclass letters, subclass numbers, cutter numbers, trailing stuff (date) */
742 var patt1 = /^([A-Z]{1,3})\s*(\d+(?:\.\d+)?)\s*(\.[A-Z]\d*)\s*([A-Z]\d*)?\s*(\d\d\d\d(?:-\d\d\d\d)?)?\s*(.*)$/i;
743 var result = callnum.match(patt1);
745 callnum = result.slice(1).join('\t');
747 callnum = callnum.split(/\s+/).join('\t');
750 /* If result is null, leave callnum alone. Can't parse this malformed call num */
752 callnum = callnum.split(/\s+/).join('\t');
756 callnum = prefix + '\t' + callnum;
759 callnum += '\t' + suffix;
762 /* At this point, the call number pieces are separated by tab characters. This allows
763 * some space-containing constructs like "v. 1" to appear on one line
765 callnum = callnum.replace(/\t\t/g, '\t'); /* Squeeze out empties */
766 names = callnum.split('\t');
767 var j = 0; var tb = [];
773 var name = names.shift();
777 /* if the name is greater than the label width... */
778 if (name.length > w) {
779 /* then try to split it on periods */
780 var sname = name.split(/\./);
781 if (sname.length > 1) {
782 /* if we can, then put the periods back in on each splitted element */
783 if (name.match(/^\./)) sname[0] = '.' + sname[0];
784 for (var k = 1; k < sname.length; k++) sname[k] = '.' + sname[k];
785 /* and put all but the first one back into the names array */
786 names = sname.slice(1).concat(names);
787 /* if the name fragment is still greater than the label width... */
788 if (sname[0].length > w) {
789 /* then just truncate and throw the rest back into the names array */
790 tb[j] = sname[0].substr(0, w);
791 names = [sname[0].substr(w)].concat(names);
793 /* otherwise we're set */
797 /* if we can't split on periods, then just truncate and throw the rest back into the names array */
798 tb[j] = name.substr(0, w);
799 names = [name.substr(w)].concat(names);
802 /* otherwise we're set */
809 return tb.join('\n');
813 .filter("columnRowRange", function () {
814 return function (i) {
816 for (var j = 0; j < i; j++) {
823 //Accepts $scope.preview_scope.copies and $scope.preview_scope.toolbox_settings as its parameters.
824 .filter("labelOutputRows", function () {
825 return function (copies, settings) {
826 var cols = [], rows = [];
827 for (var j = 0; j < (settings.page.start_position.row - 1) ; j++) {
829 for (var k = 0; k < settings.page.dimensions.columns; k++) {
830 cols.push({ c: null, index: k, cls: getPrintLabelOutputClass(k, settings), styl: getPrintLabelStyle(k, settings) });
832 rows.push({ columns: cols });
835 for (var j = 0; j < (settings.page.start_position.column - 1) ; j++) {
836 cols.push({ c: null, index: j, cls: getPrintLabelOutputClass(j, settings), styl: getPrintLabelStyle(j, settings) });
839 for (var j = 0; j < copies.length; j++) {
840 for (var n = 0; n < settings.page.label.set.size; n++) {
841 if (m < settings.page.dimensions.columns) {
842 cols.push({ c: copies[j], index: cols.length, cls: getPrintLabelOutputClass(m, settings), styl: getPrintLabelStyle(m, settings) });
845 if (m === settings.page.dimensions.columns) {
847 rows.push({ columns: cols });
849 n = settings.page.label.set.size;
853 cols.length > 0 ? rows.push({ columns: cols }) : false;
854 if (rows.length > 0) {
855 while ((rows[(rows.length - 1)].columns.length) < settings.page.dimensions.columns) {
856 rows[(rows.length - 1)].columns.push({ c: null, index: rows[(rows.length - 1)].columns.length, cls: getPrintLabelOutputClass(rows[(rows.length - 1)].columns.length, settings), styl: getPrintLabelStyle(rows[(rows.length - 1)].columns.length, settings) });
863 .filter('wrap', function () {
864 return function (input, w, wrap_type, indent) {
867 if (!w) return input;
868 if (!indent) indent = '';
870 function wrap_on_space(
874 if_cant_wrap_then_truncate,
878 console.log('possible infinite recursion, aborting');
881 if (String(text).length <= length) {
884 var truncated_text = String(text).substr(0, length);
885 var pivot_pos = truncated_text.lastIndexOf(' ');
886 var left_chunk = text.substr(0, pivot_pos).replace(/\s*$/, '');
887 var right_chunk = String(text).substr(pivot_pos + 1);
890 if (left_chunk.length == 0) {
891 if (if_cant_wrap_then_truncate) {
892 wrapped_line = truncated_text;
903 right_chunk.length > length
908 if_cant_wrap_then_truncate,
921 output = wrap_on_space(input, w, true, false, 0);
924 output = wrap_on_space(input, w, false, false, 0);
932 function getPrintLabelOutputClass(index, settings) {
933 return settings.page.column_class[index % settings.page.label.set.size];
936 function getPrintLabelStyle(index, settings) {
937 return index > 0 && (index % settings.page.label.set.size === 0) ? settings.page.label.gap.size : "";