Using link_annotation with :Desc option in Prawn PDF - ruby-on-rails

I have been struggling to link a text heading with a specific page in the Pdf, similar to the linking of Table of Contents in the Pdf file. I have found link_annotation method to achieve this however there isn't suffice documentation/examples available to use link_annotation method with :Desc option.
Any ideas how to use link_annotation with :Desc option?
Link Annotation Documentation: https://www.rubydoc.info/gems/prawn-core/Prawn%2FDocument%2FAnnotations:link_annotation

For linking text to specific page at specific offset, Destinations
class provide many helper methods. By using dest_xyz, text can be linked to specific page at specific offset.
Here is the working example which links text from 1st page to text at 2nd page at specific offset.
require 'Prawn'
margin = 36.0
extra_clickable_margin = 4.0
top_offset = 500.0
#pdf = Prawn::Document.new(margin: margin, page_size: 'A4')
clickable_text = "Clickable Annotation to 2nd page at offset #{top_offset}"
text_width = #pdf.width_of(clickable_text)
text_height = #pdf.height_of(clickable_text)
cursor = #pdf.cursor
#pdf.text clickable_text
left = margin
top = cursor + margin + extra_clickable_margin
bottom = top - text_height - extra_clickable_margin
right = left + text_width
src_rect = [left, bottom, right, top]
#pdf = Prawn::Document.new(margin: margin, page_size: 'A4')
#pdf.start_new_page
#pdf.text 'Some Text for 2nd page. ' * 40
dest = #pdf.dest_xyz(0, top_offset, nil, #pdf.state.pages[1])
#pdf.link_annotation(src_rect, Dest: dest)

Related

How to align text in center using jspdf

How to align text center using jsPDF.
var doc = new jsPDF();
doc.text(40, 250, 'Hi How are you');
If you are using the latest version (1.1.135) the api has changed some for the text function. It now reads as:
API.text = function(text, x, y, flags, angle, align);
If you don't need to use the flags or angle though, you can simply use:
var doc = new jsPDF();
doc.text('Hi How are you', 40, 250, 'center');
Keep in mind that the center call uses the x parameter now as the center of the text string, and not the left most border as it does when rendering left aligned.
Link to source
Edit:
Alternately you can calculate the proper x offset to just use the text function normally like so:
var text = "Hi How are you",
xOffset = (doc.internal.pageSize.width / 2) - (doc.getStringUnitWidth(text) * doc.internal.getFontSize() / 2);
doc.text(text, xOffset, 250);
Angular 6.
Footer align to horizontally center
var doc = new jsPDF();
var pageHeight = doc.internal.pageSize.height || doc.internal.pageSize.getHeight();
var pageWidth = doc.internal.pageSize.width || doc.internal.pageSize.getWidth();
// FOOTER
let str = "Your footer text";
doc.setTextColor(100);
doc.setFontSize(10);
doc.text(str, pageWidth / 2, pageHeight - 10, {align: 'center'});
doc.save("example.pdf");
Above answers didn't work for me, I ended up doing the following to center the text
let textX = (doc.internal.pageSize.getWidth() - doc.getTextWidth(text))/2
doc.text(text, textX, textY);
this worked:
var xOffset = doc.internal.pageSize.width / 2
doc.text('hello world', xOffset, 8, {align: 'center'});
2022: this works assuming your page width is 210 (default A4).
doc.text("This is centred text.", 105, 80, null, null, "center");
Here's a link to their live demo per the README:
http://raw.githack.com/MrRio/jsPDF/master/index.html
2022: I'm finding that JSPDF is buggy. It took a while to figure out how to install the advertised 'runs in a browser' implementation for a PHP app instead of a JS front end framework. There's a line that's required window.jsPDF = window.jspdf.jsPDF; that isn't mentioned anywhere in the documentation, I had to go through a downloaded example piece by piece to find it. Now I'm finding that the center text function doesn't work. In 2 different local environments and a JSFiddle, on multiple browsers, it sends the text off the left side of the page when the align:center option is implemented. While the above solution works, it breaks down if text is longer than one line, which, incidentally, is another out of the box bug - the text runs out of the document instead of wrapping, and there is no wrap option. So, it seems after all these hours I'm out of luck and I'll have to go a different route. Plugin is not maintained and this should be noted in documentation. Recommend to not waste your time.
This works somewhat, but isn't precise, if you know please tell me why.
I calculate the width of my text in order to center it myself.
For this, I used the getTextDimensions() method on my jsPDF object
var pdf = new jsPDF({
orientation : 'p',
unit: 'px',
format: [500, 750],
putOnlyUsedFonts:true
});
var textDimensions = pdf.getTextDimensions('MyText');
You can now use textDimensions.w to get text-width and textDimensions.h for height
Then use this to center your text.
var textWidth = textDimensions.w;
pdf.text('MyText', (pdfWidth / 2) - (textWidth / 2), 100);
BUT: You need to know your PDF's width to do this.
I 'solved' this by defining height and width myself, but you can easily find height and width of common formats online.
Like A4: 210mm*297mm.
Just remember to set unit: 'mm' when creating your jsPDF.
var doc = new jsPDF();
// set midPage for variable use
var midPage = doc.internal.pageSize.getWidth()/2
// Default is 210 mm so default midway by value is 105
doc.setFontSize(40);
doc.text("Octonyan loves jsPDF", 105, 15, null, null, "center");
// Better to use a variable "midPage" (from above)
doc.setFontSize(30);
doc.text("Centered (USA), Centred (UK)", midPage , 30, null, null, "center");

awesome wm taglist size

Can't find any manual about changing width of taglist element size.
Taglist element is wider than icons I had set. It looks really awful =(
Screenshot: http://s12.postimg.org/fkva7xywd/Screenshot_16_02_2014_16_04_07.png
Taglist element consist of icon, text and gap between them. This gap defined in awful.widget.common.list_update function in line
m = wibox.layout.margin(tb, 4, 4)
Despite you have no text, double gap is still here. To solve this problem you can copy list_update function to your rc file, fix it and send as fifth(!) argument in awful.widget.taglist.
just tell your imagebox not to be resizable, example:
wibox.widget.imagebox(beautiful.clock, false)
or you can even resize you wibox:
mywibox[s] = awful.wibox({ position = "top", screen = s, height = 32 })
you just need to modify height value
or another method using wibox.layout.constraint:
clock_icon = wibox.widget.imagebox(beautiful.clock, true)
local const = wibox.layout.constraint()
const:set_widget(clock_icon)
const:set_strategy("exact")
const:set_height(16)
then, instead of adding your icon to the layout, just add the constraint.

Awesome 3.5 - two panels (wiboxes) at the top

Before migrating to Awesome 3.5.1 I had two panels at the top of my screen (on top of each other, sort of) and none at the bottom. The code I used to achieve this pre-3.5.* is below:
-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", height = "32", screen = s })
-- Add widgets to the wibox - order matters
mywibox[s].widgets = {
{
{
-- Upper left section
mylauncher,
mytaglist[s],
mypromptbox[s],
-- My custom widgets, separators etc...
layout = awful.widget.layout.horizontal.leftright
},
{
-- Upper right section
mylayoutbox[s],
mytextclock,
-- More widgets, separators, etc...
s == 1 and mysystray or nil,
layout = awful.widget.layout.horizontal.rightleft
},
},
{
-- Lower section (only the tasklist)
mytasklist[s],
},
layout = awful.widget.layout.vertical.flex,
height = mywibox[s].height
}
Now I'm having a hard time trying to figure out how to achieve the same with the 3.5 configuration. At the moment I use pretty basic one panel (with most of the widgets) on top, and one (with the tasklist) at the bottom. The code can be seen below:
-- Create the wibox
mywibox[s] = awful.wibox({ position = "top", height = "18", screen = s })
mywibox2[s] = awful.wibox({ position = "bottom", height = "18", screen = s })
-- Widgets that are aligned to the left
local left_layout = wibox.layout.fixed.horizontal()
left_layout:add(mylauncher)
left_layout:add(mytaglist[s])
left_layout:add(mypromptbox[s])
-- My custom widgets, separators, etc...
-- Widgets that are aligned to the right
local right_layout = wibox.layout.fixed.horizontal()
if s == 1 then right_layout:add(wibox.widget.systray()) end
-- My custom widgets, separators, etc...
right_layout:add(mytextclock)
right_layout:add(mylayoutbox[s])
-- Now bring it all together
local layout = wibox.layout.align.horizontal()
layout:set_left(left_layout)
layout:set_right(right_layout)
local layout2 = wibox.layout.align.horizontal()
layout2:set_middle(mytasklist[s])
mywibox[s]:set_widget(layout)
mywibox2[s]:set_widget(layout2)
If anyone has ideas how to edit my current rc.lua to make it work as the upper code did in Awesome 3.4.*, that'd be greatly appreciated.
You could try something like this, no idea if it does exactly what you want (32 is the height of your wibox according to your code):
local const = wibox.layout.constraint()
const:set_widget(layout)
const:set_strategy("exact")
const:set_height(32/2)
local l = wibox.layout.fixed.vertical()
l:add(const)
l:add(mytasklist[s])
mywibox[s]:set_widget(l)
First it creates a "constraint" layout which makes sure that the layout "layout" (the widgets that should be shown on the top) always get a size of 16px. Then it stacks this constraint layout ontop of the tasklist and displays the result in the wibox.
Some of this code could be shortened a bit in the latest version, but I am not sure if 3.5.1 has those convenience arguments already.
I've done similar with following code:
wiboxes["top"]=awful.wibox({position="top",height=26})
local top_layout = wibox.layout.fixed.horizontal()
sublayout["cpu"] = wibox.layout.fixed.horizontal()
for i=2,3 do
sublayout["cpu" .. i] = wibox.layout.fixed.horizontal()
sublayout["cpu" .. i]:add(graphs["cpu"]..i) -- the graphs table already initialized
sublayout["cpu" .. i]:add(textboxes["cpu"]..i) -- textboxes table already initialized
sublayout["cpu"]:add(sublayout["cpu"..i)
end
.....
top_layout:add(sublayout["cpu"])
.....
wiboxes["top"]:set_widget(top_layout)
With this code I've two graphs and textboxes to see the CPUs usage (every core), first is on top, second is down. It should work with taglist or any other widget.

How do I adjust where the calendar appears for the datePicker in the Grails UI plugin without the position changing when the page is resized?

I wanted to change where the calendar appeared for the datePicker portion of the Grails UI plugin. After a bit of digging, I found it in the InputTagLib.groovy file:
out << """
YAHOO.util.Event.on("${showButtonId}", "click", function() {
var buttonRegion = YAHOO.util.Dom.getRegion('${showButtonId}');
var buttonHeight = buttonRegion.bottom - buttonRegion.top;
var buttonWidth = buttonRegion.right - buttonRegion.left;
var xy = YAHOO.util.Dom.getXY('${showButtonId}');
var newXY = [xy[0] + buttonWidth, xy[1] + buttonHeight];
YAHOO.util.Dom.setXY('${id}_calContainer_c', newXY);
GRAILSUI.${jsid}Panel.show();
if (YAHOO.env.ua.opera && document.documentElement) {
// Opera needs to force a repaint
document.documentElement.className += "";
}
});"""
The position is set on this line:
YAHOO.util.Dom.setXY('${id}_calContainer_c', newXY);
The YAHOO.util.Dom.setXY() method takes two arguments.
The first argument of the setXY method is either the ID of an HTMLElement, or an actual HTMLElement object. The second argument is an array containing two values: [x, y] where x is the distance from the left edge of the document, and y is the distance from the top edge of the document.
Source: http://developer.yahoo.com/yui/examples/dom/setxy.html
So I can easily adjust where the calendar appears by changing the values in the newXY variable that is passed to the setXY method and it works fine.
However, if I resize the page, the calendar positions its top left corner directly under the showButton's bottom left corner. What is it that makes the repositioning happen when the page is resized and how can I resolve it?
EDIT : A little more info:
This happens in the most recent versions of IE, Firefox, and Chrome
If I resize the page and then click the button to show the calendar, the calendar shows in the expected place but it will reposition if I resize the page again once the calendar is open

ExtJS Quicktip constrains problem

I've got a column renderer defined that creates a HTML fragment which contains the ext.qtip attributes to create a quicktip. All works fine, the image renders in the grid cell, when i hover over the image a tooltip with the larger image is shown ... all nice but the quicktip on the bottom row expands beyond the constraints of the panel, is there any way to make it stay inside the panel boundaries?
var thumbRenderer = function(value, meta, record){
var thumbPath = Config.baseUrl + 'images/thumb/' + record.get('filename');
var previewPath = Config.baseUrl + 'images/big/' + record.get('filename');
return String.format('<img src="{0}" ext:qwidth="312" ext:qtip="<img style=\'margin: 2px 0;width:300px;\' src=\'{1}\' />" width="60" class="pic" />', thumbPath, previewPath);
}
You may want to look at the showAt method:
tip.showAt([x,y]);
Where x and y are the respective x and y co-ordinate positions.
EDIT: You can also use the showBy() method on a QuickTip instance:
http://dev.sencha.com/deploy/dev/docs/source/Tip.html#method-Ext.Tip-showBy

Resources