Simple PDF viewer

Mac OSX specific forum
User avatar
Shardik
Addict
Addict
Posts: 1982
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Simple PDF viewer

Post by Shardik »

Have you ever had the need to display PDF documents in your own Mac application?
In contrast to Windows (where you have to buy 3rd party products like the high
priced Adobe Acrobat or other products or where you have to fight with the poorly
documented API of the Adobe Reader) MacOS X offers all the necessary API functions
to display PDF documents in your own applications. The following code example
demonstrates the basics of a very simple PDF viewer:

Code: Select all

EnableExplicit

ImportC ""
  CFStringCreateWithCString(CFAllocatorRef.L, CString, CFStringEncoding.L)
  CFRelease(CFTypeRef.L)
  CFURLCreateWithFileSystemPath(CFAllocatorRef.L, CFStringFilePath.L, PathStyle.L, IsDirectory.L)
  CGContextDrawPDFPage(CGContextRef.L, CGPDFPageRef.L)
  CGPDFDocumentCreateWithURL(CFURLRef.L)
  CGPDFDocumentGetNumberOfPages(PDFDocumentRef.L)
  CGPDFDocumentGetPage(PDFDocumentRef.L, PageNumber.L)
  CGPDFDocumentRelease(PDFDocumentRef.L)
  GetWindowPort(WindowRef.L)
  QDBeginCGContext(*ColorGraphicsPort, *CGContextRef)
  QDEndCGContext(*ColorGraphicsPort, *CGContextRef)
EndImport

#kCFAllocatorDefault = 0
#kCFStringEncodingMacRoman = 0
#kCFURLPOSIXPathStyle = 0

Procedure.L OpenPDFDocument(PathAndPDFFilename.S)
  Protected FilePathRef.L
  Protected PDFDocumentRef.L
  Protected URLRef.L

  ; ----- Convert PDF file path from PureBasic String into Core Foundation
  ;       string (CFString)
  FilePathRef = CFStringCreateWithCString(#kCFAllocatorDefault, @PathAndPDFFilename, #kCFStringEncodingMacRoman)

  If FilePathRef
    ; ----- Create CFURL object using CFString with local file system path
    URLRef = CFURLCreateWithFileSystemPath(#kCFAllocatorDefault, FilePathRef, #kCFURLPOSIXPathStyle, #False)
   
    If URLRef
      ; ----- Create Quartz PDF document with URL of PDF file
      PDFDocumentRef = CGPDFDocumentCreateWithURL(URLRef)
      CFRelease(URLRef)
    EndIf

    CFRelease(FilePathRef)
  EndIf

  ProcedureReturn PDFDocumentRef
EndProcedure

Procedure DrawPDFPage(PDFDocumentRef.L, PageNumber.L)
  Protected ContextRef.L
  Protected *GraphicsPort
  Protected PDFPageRef.L

  ; ----- Read page from Quartz PDF document
  PDFPageRef = CGPDFDocumentGetPage(PDFDocumentRef, PageNumber)
  
  If PDFPageRef
    ; ----- Obtain ColorGraphicsPort of window
    *GraphicsPort = GetWindowPort(WindowID(0))
    
    If *GraphicsPort
      ; ----- Obtain Quartz 2D drawing environment associated with graphics port
      QDBeginCGContext(*GraphicsPort, @ContextRef)
      
      If ContextRef
        ; ----- Draw PDF page into current graphics context
        CGContextDrawPDFPage(ContextRef, PDFPageRef)

        ; ----- Terminate Quartz 2D drawing environment
        QDEndCGContext(*GraphicsPort, @ContextRef)
      EndIf
    EndIf
  EndIf
EndProcedure

Define CurrentPage.L
Define LastPage.L
Define PathAndPDFFilename.S
Define PDFDocumentRef.L
Define WindowEvent.L

OpenWindow(0, 200, 50, 580, 790, "PDF-Viewer")
SetWindowColor(0, $FFFFFF)

; ----- Draw ToolBar buttons for one page back and forward
CreateImage(0,16,16)
StartDrawing(ImageOutput(0))
Box(0, 0, 16, 16, $FFFFFF)
DrawText(3, 0, "<", 0, $FFFFFF)
StopDrawing()
CreateImage(1,16,16)
StartDrawing(ImageOutput(1))
Box(0, 0, 16, 16, $FFFFFF)
DrawText(5, 0, ">", 0, $FFFFFF)
StopDrawing()
CreateToolBar(0, WindowID(0))
ToolBarImageButton(0,ImageID(0))
ToolBarImageButton(1,ImageID(1))

; ----- Create Quartz PDF object
PathAndPDFFilename = "/Developer/Documentation/CHUD/Saturn/SaturnUserGuide.pdf"
PDFDocumentRef = OpenPDFDocument(PathAndPDFFilename)

If PDFDocumentRef
  CurrentPage = 1
  LastPage = CGPDFDocumentGetNumberOfPages(PDFDocumentRef)
  DrawPDFPage(PDFDocumentRef, CurrentPage)

  Repeat
    WindowEvent = WaitWindowEvent()
    
    Select WindowEvent
      Case #PB_Event_Repaint
        DrawPDFPage(PDFDocumentRef, CurrentPage)
      Case #PB_Event_Menu
        Select EventMenu()
          Case 0
            If CurrentPage > 1
              CurrentPage - 1
            EndIf
          Case 1
            If CurrentPage < LastPage
              CurrentPage + 1
            EndIf
        EndSelect

        SetWindowColor(0, $FFFFFF)
        DrawPDFPage(PDFDocumentRef, CurrentPage)
    EndSelect
  Until WindowEvent = #PB_Event_CloseWindow

  ; ----- Release Quartz PDF document
  CGPDFDocumentRelease(PDFDocumentRef)
EndIf
WilliamL
Addict
Addict
Posts: 1212
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Simple PDF viewer

Post by WilliamL »

Nice! Works fine here.

Code: Select all

; to load your own PDF
;PathAndPDFFilename = "/Developer/Documentation/CHUD/Saturn/SaturnUserGuide.pdf"
PathAndPDFFilename = OpenFileRequester("Load PDF file...", "", "", 0) ; pattern$ doesn't work on Mac
PDFDocumentRef = OpenPDFDocument(PathAndPDFFilename)
Thanks Shardik :)

@zabenka
Are you on a Mac? You don't need (or want) Acrobat Reader to get involved this, the PDF viewer runs in PureBasic.
MacBook Pro-M1 (2021), Sonoma 14.3.1, PB 6.10b7 M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Simple PDF viewer

Post by wilbert »

I get missing symbols on x64.

Here's an alternative approach.
It's probably not as flexible but seems to work

Code: Select all

ImportC "/System/Library/Frameworks/Quartz.framework/Quartz" : EndImport

Procedure PDFGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFGadgetCatchPDF(PDFGadget, *MemoryAddress, Size)
  Protected Viewer, Doc, PDFData
  PDFData = CocoaMessage(0, 0, "NSData dataWithBytes:", *MemoryAddress, "length:", Size)
  Doc = CocoaMessage(0, CocoaMessage(0, 0, "PDFDocument alloc"), "initWithData:", PDFData)
  If Doc
    Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
    CocoaMessage(0, Viewer, "setDocument:", Doc)
    CocoaMessage(0, Doc, "release")
  EndIf
EndProcedure

Procedure PDFGadgetLoadPDF(PDFGadget, Filename$)
  Protected PDFData = CocoaMessage(0, 0, "NSData dataWithContentsOfFile:$", @Filename$)
  If PDFData
    PDFGadgetCatchPDF(PDFGadget, CocoaMessage(0, PDFData, "bytes"), CocoaMessage(0, PDFData, "length"))
  EndIf
EndProcedure

Procedure.s PDFGadgetGetText(PDFGadget)
  Protected Result.s, Document = CocoaMessage(0, CocoaMessage(0, GadgetID(PDFGadget), "contentView"), "document")
  If Document
    Result = PeekS(CocoaMessage(0, CocoaMessage(0, Document, "string"), "UTF8String"), -1, #PB_UTF8)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFThumbnailView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadgetSetPDFGadget(PDFThumbnailGadget, PDFGadget)
  Protected ThumbnailViewer = CocoaMessage(0, GadgetID(PDFThumbnailGadget), "contentView")
  Protected Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
  CocoaMessage(0, ThumbnailViewer, "setPDFView:", Viewer)
EndProcedure



If OpenWindow(0, 0, 0, 600, 400, "PDF Viewer example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  PDFGadget(0, 120, 10, 460, 300, #PB_Container_Flat)
  PDFThumbnailGadget(1, 10, 10, 100, 380, #PB_Container_Flat)
  EditorGadget(2, 120, 320, 460, 70, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
  PDFThumbnailGadgetSetPDFGadget(1, 0)
  PDFGadgetLoadPDF(0, "test.pdf")
  SetGadgetText(2, PDFGadgetGetText(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Edit : I just notice this was a very old thread that came to the front due to a spam message. Well, maybe someone can use my code anyhow.
Last edited by wilbert on Fri Jun 14, 2013 6:41 pm, edited 2 times in total.
Windows (x64)
Raspberry Pi OS (Arm64)
WilliamL
Addict
Addict
Posts: 1212
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Simple PDF viewer

Post by WilliamL »

Hi wilbert!

Your code works fine here. I just wish there was a way to get the text from the displayed pdf. I was looking at your code and trying to figure out if the text could be copied out of the containers like we do with GetGadgetText().

I guess getting the text out of a pdf is pretty hard since all I see are programs that can do it are being sold for $s. I bought an app to read pdfs but I keep looking for a pb way to do it anyway.
MacBook Pro-M1 (2021), Sonoma 14.3.1, PB 6.10b7 M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Simple PDF viewer

Post by wilbert »

WilliamL wrote:I guess getting the text out of a pdf is pretty hard since all I see are programs that can do it are being sold for $s.
Actually it's easy (see updated example above).
If you don't need to display the PDF but only want its text, it's even easier

Code: Select all

ImportC "/System/Library/Frameworks/Quartz.framework/Quartz" : EndImport

PDFFile.s = "test.pdf"
PDFDocument = CocoaMessage(0, CocoaMessage(0, 0, "PDFDocument alloc"), "initWithURL:", CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @PDFFile))
PDFText.s = PeekS(CocoaMessage(0, CocoaMessage(0, PDFDocument, "string"), "UTF8String"), -1, #PB_UTF8)
CocoaMessage(0, PDFDocument, "release")
MessageRequester("", PDFText)
Windows (x64)
Raspberry Pi OS (Arm64)
WilliamL
Addict
Addict
Posts: 1212
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: Simple PDF viewer

Post by WilliamL »

Hey wilbert!

That works! I like the way you modified your first example with the EditorGadget. :D

Now that I have the text and can play with it...

[later]
ok, it works fine with paragraphs but I get lists for columns (tables) a column at a time. It's pretty confusing. I think I read somewhere that the formatting of the text would be hosed.. and it is. It's too bad that the column elements don't have LFs (or some other delimiter) and CRs at the end of the lines.. but they don't. It's all CRs.

Ah, the 'devil is in the details'.
MacBook Pro-M1 (2021), Sonoma 14.3.1, PB 6.10b7 M1
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Simple PDF viewer

Post by wilbert »

WilliamL wrote:ok, it works fine with paragraphs but I get lists for columns (tables) a column at a time. It's pretty confusing. I think I read somewhere that the formatting of the text would be hosed.. and it is. It's too bad that the column elements don't have LFs (or some other delimiter) and CRs at the end of the lines.. but they don't. It's all CRs.
It's possible to get it as html text but I don't know if that would make a difference.
Windows (x64)
Raspberry Pi OS (Arm64)
spacebuddy
Enthusiast
Enthusiast
Posts: 346
Joined: Thu Jul 02, 2009 5:42 am

Re: Simple PDF viewer

Post by spacebuddy »

is there anyway to create a pdf file using text?
coder14
Enthusiast
Enthusiast
Posts: 327
Joined: Tue Jun 21, 2011 10:39 am

Re: Simple PDF viewer

Post by coder14 »

Built in PDF? Marvelous! Thank you guys. :D

I tried both but can't get Shardik's code to work. It's lower level and more functions but fails at CGPDFDocumentCreateWithURL.

I modified and extended wilbert's code to load with "PDFDocument alloc initWithURL" and added the password and page functions and they work - SO FAR!

But when trying to get the dimensions of a page with boundsForBox: with any enumeration value the function fails with "boundsForBox: box is out of range".

What is causing this?
victorprogra
User
User
Posts: 23
Joined: Wed Jul 06, 2022 3:49 pm

Re: Simple PDF viewer

Post by victorprogra »

Hi,
Can't get this code to run, I would appreciate help:
PureBasic - Linker error:
clang: error: no such file or directory: '/System/Library/Frameworks/Quartz.framework/Quartz'

Running PureBasic 6.0.3 LTS on macOS Ventura 13.6


From:
wilbert post_id=414739 time=1371185023 user_id=1283

Code: Select all

ImportC "/System/Library/Frameworks/Quartz.framework/Quartz" : EndImport

Procedure PDFGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFGadgetCatchPDF(PDFGadget, *MemoryAddress, Size)
  Protected Viewer, Doc, PDFData
  PDFData = CocoaMessage(0, 0, "NSData dataWithBytes:", *MemoryAddress, "length:", Size)
  Doc = CocoaMessage(0, CocoaMessage(0, 0, "PDFDocument alloc"), "initWithData:", PDFData)
  If Doc
    Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
    CocoaMessage(0, Viewer, "setDocument:", Doc)
    CocoaMessage(0, Doc, "release")
  EndIf
EndProcedure

Procedure PDFGadgetLoadPDF(PDFGadget, Filename$)
  Protected PDFData = CocoaMessage(0, 0, "NSData dataWithContentsOfFile:$", @Filename$)
  If PDFData
    PDFGadgetCatchPDF(PDFGadget, CocoaMessage(0, PDFData, "bytes"), CocoaMessage(0, PDFData, "length"))
  EndIf
EndProcedure

Procedure.s PDFGadgetGetText(PDFGadget)
  Protected Result.s, Document = CocoaMessage(0, CocoaMessage(0, GadgetID(PDFGadget), "contentView"), "document")
  If Document
    Result = PeekS(CocoaMessage(0, CocoaMessage(0, Document, "string"), "UTF8String"), -1, #PB_UTF8)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFThumbnailView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadgetSetPDFGadget(PDFThumbnailGadget, PDFGadget)
  Protected ThumbnailViewer = CocoaMessage(0, GadgetID(PDFThumbnailGadget), "contentView")
  Protected Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
  CocoaMessage(0, ThumbnailViewer, "setPDFView:", Viewer)
EndProcedure



If OpenWindow(0, 0, 0, 600, 400, "PDF Viewer example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  PDFGadget(0, 120, 10, 460, 300, #PB_Container_Flat)
  PDFThumbnailGadget(1, 10, 10, 100, 380, #PB_Container_Flat)
  EditorGadget(2, 120, 320, 460, 70, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
  PDFThumbnailGadgetSetPDFGadget(1, 0)
  PDFGadgetLoadPDF(0, "test.pdf")
  SetGadgetText(2, PDFGadgetGetText(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
DayDreamer
User
User
Posts: 17
Joined: Thu Aug 03, 2023 5:44 pm

Re: Simple PDF viewer

Post by DayDreamer »

Not fancy but even less code, try just using WebGadget to load PDF file.
mrbungle
Enthusiast
Enthusiast
Posts: 110
Joined: Wed Dec 30, 2020 3:18 am

Re: Simple PDF viewer

Post by mrbungle »

try this:

Code: Select all

ImportC "-framework Quartz" : EndImport
victorprogra wrote: Tue Nov 14, 2023 9:04 pm Hi,
Can't get this code to run, I would appreciate help:
PureBasic - Linker error:
clang: error: no such file or directory: '/System/Library/Frameworks/Quartz.framework/Quartz'

Running PureBasic 6.0.3 LTS on macOS Ventura 13.6


From:
wilbert post_id=414739 time=1371185023 user_id=1283

Code: Select all

ImportC "/System/Library/Frameworks/Quartz.framework/Quartz" : EndImport

Procedure PDFGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFGadgetCatchPDF(PDFGadget, *MemoryAddress, Size)
  Protected Viewer, Doc, PDFData
  PDFData = CocoaMessage(0, 0, "NSData dataWithBytes:", *MemoryAddress, "length:", Size)
  Doc = CocoaMessage(0, CocoaMessage(0, 0, "PDFDocument alloc"), "initWithData:", PDFData)
  If Doc
    Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
    CocoaMessage(0, Viewer, "setDocument:", Doc)
    CocoaMessage(0, Doc, "release")
  EndIf
EndProcedure

Procedure PDFGadgetLoadPDF(PDFGadget, Filename$)
  Protected PDFData = CocoaMessage(0, 0, "NSData dataWithContentsOfFile:$", @Filename$)
  If PDFData
    PDFGadgetCatchPDF(PDFGadget, CocoaMessage(0, PDFData, "bytes"), CocoaMessage(0, PDFData, "length"))
  EndIf
EndProcedure

Procedure.s PDFGadgetGetText(PDFGadget)
  Protected Result.s, Document = CocoaMessage(0, CocoaMessage(0, GadgetID(PDFGadget), "contentView"), "document")
  If Document
    Result = PeekS(CocoaMessage(0, CocoaMessage(0, Document, "string"), "UTF8String"), -1, #PB_UTF8)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadget(Gadget, x, y, Width, Height, Flags = 0)
  Protected Result, ContainerID, Viewer, Frame.NSRect
  Result = ContainerGadget(Gadget, x, y, Width, Height, Flags)
  CloseGadgetList()
  If Gadget = #PB_Any
    ContainerID = GadgetID(Result)
  Else
    ContainerID = GadgetID(Gadget)
  EndIf
  Viewer = CocoaMessage(0, CocoaMessage(0, 0, "PDFThumbnailView alloc"), "initWithFrame:@", @Frame)
  CocoaMessage(0, ContainerID, "setContentView:", Viewer)
  CocoaMessage(0, Viewer, "release")
  ProcedureReturn Result
EndProcedure

Procedure PDFThumbnailGadgetSetPDFGadget(PDFThumbnailGadget, PDFGadget)
  Protected ThumbnailViewer = CocoaMessage(0, GadgetID(PDFThumbnailGadget), "contentView")
  Protected Viewer = CocoaMessage(0, GadgetID(PDFGadget), "contentView")
  CocoaMessage(0, ThumbnailViewer, "setPDFView:", Viewer)
EndProcedure



If OpenWindow(0, 0, 0, 600, 400, "PDF Viewer example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  PDFGadget(0, 120, 10, 460, 300, #PB_Container_Flat)
  PDFThumbnailGadget(1, 10, 10, 100, 380, #PB_Container_Flat)
  EditorGadget(2, 120, 320, 460, 70, #PB_Editor_ReadOnly | #PB_Editor_WordWrap)
  PDFThumbnailGadgetSetPDFGadget(1, 0)
  PDFGadgetLoadPDF(0, "test.pdf")
  SetGadgetText(2, PDFGadgetGetText(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
victorprogra
User
User
Posts: 23
Joined: Wed Jul 06, 2022 3:49 pm

Re: Simple PDF viewer

Post by victorprogra »

That did it, now it works perfect!
Thank you very much mrbungle :D
User avatar
Piero
Enthusiast
Enthusiast
Posts: 279
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Man PDF viewer

Post by Piero »

mp.sh

Code: Select all

#!/bin/sh
man -t $1 > /tmp/$1.ps
open /tmp/$1.ps
Fred
Administrator
Administrator
Posts: 16522
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Simple PDF viewer

Post by Fred »

it's a PB forums, please post PureBasic code.
Post Reply