நீங்கள் ஒரு PDF-லிருந்து தடித்த (bold) அல்லது சாய்ந்த (italic) உரையை எடுக்க முயன்றிருந்தால், நீங்கள் ஒரு regex மூலம் தான் தொடங்கியிருப்பீர்கள். இது ஒரு இயல்பான நடவடிக்கையாகத் தோன்றும். எழுத்துருவின் (font) பெயரில் “Bold” என்ற வார்த்தையைத் தேடி, அந்த உரையைத் தடித்ததாகக் குறித்துக்கொண்டு அடுத்த கட்டத்திற்குச் செல்வது. அந்த உத்தி உங்களுக்குத் தவறான நம்பிக்கையைத் தரும் அளவிற்கு மட்டுமே வேலை செய்யும். பிறகு யாராவது அதே ஆவணத்தை Acrobat-ன் வேறு பதிப்பிலிருந்தோ, அல்லது LibreOffice-லிருந்தோ, அல்லது print-to-PDF driver-லிருந்தோ ஏற்றுமதி (export) செய்தால், நீங்கள் குறியீடு செய்த அனைத்து அனுமானங்களும் உடைந்துவிடும்.

எழுத்துருப் பெயர்கள் ஏன் பொய் சொல்கின்றன

PDF.js உங்களுக்கு ABCDEF+TimesNewRomanPS-BoldMT போன்ற சரங்களை (strings) வழங்கும். முதல் ஆறு எழுத்துக்கள் ஏற்றுமதி செய்யப்படும்போது சேர்க்கப்படும் ஒரு சீரற்ற முன்னொட்டு (random prefix) ஆகும், மேலும் கோப்பு மீண்டும் உருவாக்கப்படும் ஒவ்வொரு முறையும் இவை மாறும். உங்கள் parser-ஐ அந்த முன்னொட்டின் அடிப்படையில் அமைப்பது என்பது தேவையற்ற இரைச்சலை (noise) நம்புவதற்குச் சமம். மற்ற ஏற்றுமதி கருவிகள் இன்னும் குறைவான உதவியையே வழங்கும். சில Font12 அல்லது F1 போன்ற வெறும் அடையாளங்களை மட்டுமே வெளியிடும். இந்த லேபிள்கள் எந்தப் பொருளுள்ள அர்த்தத்தையும் கொண்டிருக்கவில்லை; அவை கோப்பு எழுதப்படும்போது அருகாமையில் இருந்த உள் வளத் குறிகிகள் (internal resource tags) மட்டுமே.

Portable Document Format என்பது உரையை எளிதாகப் பிரித்தெடுக்கும் வகையில் வடிவமைக்கப்படாததால், எழுத்துருப் பெயர்கள் என்பது உட்பொதிக்கப்பட்ட (embedded) அல்லது துணைத் தொகுக்கப்பட்ட (subsetted) வளங்களுக்கான குறிப்புகள் மட்டுமே. அவை பாணியைக் கண்டறிவதற்கான (style detection) நிலையான API ஆகச் செயல்பட ஒருபோதும் நோக்கம் கொண்டவை அல்ல. நீங்கள் Bold அல்லது Italic என்ற துணைச் சரத்தைத் தேடும் regex-ஐ எழுதும்போது, அதை உருவாக்கிய செயலி (application) விரும்பியபடி வடிவமைத்த ஒரு லேபிளை நீங்கள் சேகரிக்கிறீர்கள். நீங்கள் உண்மையான அச்சுப் பண்புகளை (typographic properties) வாசிக்கவில்லை. நீங்கள் ஒரு கோப்புப் பெயரிடும் முறையை (file-naming convention) வாசிக்கிறீர்கள், மேலும் முறைகள் என்பது ஒப்பந்தங்கள் அல்ல.

லேபிளை அல்ல, விவரிப்பானைப் (Descriptor) படிக்கவும்

உண்மையான தகவல் வேறொரு இடத்தில் உள்ளது. PDF.js-இல், ஒவ்வொரு பக்கப் பொருளும் (page object) commonObjs என்ற வரைபடத்தை (map) வெளிப்படுத்துகிறது; இது பக்கத்தை உருவாக்கத் தேவையான உண்மையான எழுத்துரு விவரிப்பான்களைக் (font descriptors) கொண்டுள்ளது. நூலகம் (library) ஒரு பக்கத்தைப் பகுப்பாய்வு செய்யும்போது, இது உண்மையான எழுத்துருப் பொருட்களால் (font objects) இந்த வரைபடத்தை நிரப்புகிறது. அந்தப் பொருட்கள் bold மற்றும் italic ஆகியவற்றிற்கான boolean பண்புகளை வெளிப்படுத்துகின்றன. அந்த boolean மதிப்புகள் பெயர் சரத்திலிருந்து (name string) பெறப்படுவதில்லை. அவை PDF-க்குள் உட்பொதிக்கப்பட்ட எழுத்துரு விவரிப்பிலிருந்து வருகின்றன; இவை glyph metrics, OS/2 table flags மற்றும் அச்சுப்பொறியாளர் (typesetter) ஆவணத்தில் எழுதிய குறியீட்டு விவரிப்பான்களிலிருந்து பெறப்படுகின்றன.

இதன் பொருள் நீங்கள் யூகிக்க வேண்டிய அவசியமில்லை. ஒரு பக்கத்தில் உள்ள உரை உருப்படிகளை (text items) ஆய்வு செய்வதற்கு முன், page.commonObjs-ஐத் சுழற்சி (iterate) செய்வதன் மூலம் ஒரு fontStyleMap-ஐ உருவாக்கவும். ஒவ்வொரு எழுத்துரு ID-க்கும், எழுத்துருப் பொருளால் வழங்கப்படும் உண்மையான .bold மற்றும் .italic பண்புகளைப் பதிவு செய்யும் ஒரு பொருளைச் சேமிக்கவும். பின்னர், ஒவ்வொரு உரை உருப்படியையும் நீங்கள் செயலாக்கும்போது, உங்கள் வரைபடத்தில் அதன் எழுத்துருக் குறிப்பைக் கண்டறிந்து, முன்கூட்டியே கணக்கிடப்பட்ட கொடிகளை (flags) வாசிக்கவும். ஏற்றுமதி மாற்றங்களுக்கு இடையிலும் மாறாத ஒரு உறுதியான விடையை நீங்கள் திடீரென்று பெறுவீர்கள்.

நீங்கள் ஒரு மாற்று வழியை (fallback) வைத்திருக்கலாம். விவரிப்பான் ஏதேனும் ஒரு வகையில் இல்லையென்றால் அல்லது முழுமையற்றதாக இருந்தால், முன்னொட்டை நீக்கி, சீரற்ற குறிகளைத் தவிர்த்து, மீதமுள்ளவற்றிற்கு ஒரு பாதுகாப்பான regex-ஐ இயக்கவும். ஆனால் இது உங்கள் இறுதி முயற்சியாக இருக்க வேண்டுமே தவிர, முதன்மைத் தர்க்கமாக (primary logic) இருக்கக்கூடாது. நம்பகத்தன்மையின் வித்தியாசம் வியக்கத்தக்கது. பெயர் அடிப்படையிலான பகுப்பாய்வு பல்வேறு ஏற்றுமதி கருவிகளில் முறிந்து போகும் இடத்தில், விவரிப்பு அடிப்படையிலான பகுப்பாய்வு நிலையாக இருக்கும், ஏனெனில் அது கோப்பில் உண்மையில் என்ன உள்ளது என்று கேட்கிறது.

எழுத்துருவும் பொய் சொல்லும்போது: செயற்கை பாணிகள் (Synthetic Styles)

விவரிப்பால் கூட சிலவற்றைத் தவறவிட முடியும். சில PDF உருவாக்குநர்கள் தனித்த சாய்ந்த (italic) எழுத்துருவை உட்பொதிக்க முயற்சிப்பதில்லை. அதற்குப் பதிலாக, அவர்கள் நேராக இருக்கும் ரோமன் எழுத்துருவை எடுத்து ஒரு transform matrix மூலம் சாய்வாக மாற்றுகிறார்கள். வடிவமைப்பு கருவிகள் அல்லது அச்சுத் தூய்மையை விட கோப்பு அளவிற்காக முன்னுரிமை அளிக்கும் பழைய சொல் செயலாக்கிகளால் (word processors) உருவாக்கப்பட்ட கோப்புகளில் இது பொதுவானது.

PDF.js-இல் உள்ள ஒவ்வொரு உரை உருப்படியும் ஒரு transform வரிசையைக் (array) கொண்டுள்ளது; இது glyph ஆயத்தொலைவு அமைப்பை (coordinate system) பக்க ஆயத்தொலைவு அமைப்பிற்கு மாற்றும் ஆறு உறுப்புகளைக் கொண்ட ஒரு affine matrix ஆகும். அந்த வரிசையின் மூன்றாவது உறுப்பு கிடைமட்டச் சாய்வைக் (horizontal shear) கட்டுப்படுத்துகிறது. அந்த மதிப்பு பூஜ்ஜியமாக இல்லையென்றால், உரை renderer மூலம் இயந்திரரீதியாகச் சாய்வாக மாற்றப்படுகிறது. நீங்கள் எழுத்துரு விவரிப்பை மட்டும் நம்பினால், இந்த உரையை நேராக இருக்கும் ரோமனாக வகைப்படுத்துவீர்கள். நீங்கள் அந்த matrix-ஐ ஆய்வு செய்தால், செயற்கையான சாய்ந்த எழுத்துருவைக் கண்டறிந்து அதைச் சரியாகக் குறிக்கலாம். அதே தர்க்கம் overprinting மூலம் உருவாக்கப்பட்ட செயற்கை தடித்த எழுத்துருக்களுக்கும் பொருந்தும், இருப்பினும் அதை வடிவியலிலிருந்து (geometry) மட்டும் கண்டறிவது கடினம். சாய்ந்த உரையைப் பொறுத்தவரை, shear மதிப்புதான் உங்கள் முக்கிய ஆதாரமாகும்.

அடிக்கோடுகள் வரையப்படுகின்றன, அறிவிக்கப்படுவதில்லை

தடித்த மற்றும் சாய்ந்த எழுத்துருக்கள் எழுத்துருப் பண்புகள். அடிக்கோடு அப்படிப்பட்டது அல்ல. PDF-இல், ஒரு அடிக்கோடு என்பது ஒரு vector path ஆகும். உரைத் தரைமட்டத்திற்கு (text baseline) அருகில் அமைந்துள்ள ஒரு மெல்லிய கிடைமட்டப் பகுதிக்காக renderer ஒரு வரைதல் கட்டளையை (drawing command) வழங்குகிறது. இது எழுத்துக்களுக்குக் கீழே அமையும் ஒரு வரைபடக் கூறே தவிர, cmap-இல் சேமிக்கப்பட்ட ஒரு எழுத்து பண்பு (character attribute) அல்ல.

இந்த வேறுபாடு முக்கியமானது, ஏனெனில் எழுத்துரு விளக்கிகளை (font descriptors) எவ்வளவு படித்தாலும் அடிக்கோடிட்ட பகுதியை (underline) கண்டறிய முடியாது. பக்கத்தில் உள்ள மூல வரைதல் செயல்பாடுகளை (raw drawing operators) அல்லது வடிவியல்-நிலை வெளியீட்டை (geometry-level output), சரியான தூரத்தில் அடிப்படை வரிக்கு (baseline) இணையாக செல்லும் குறுகிய கிடைமட்டக் கோட்டுத் துண்டுகளைத் தேட நீங்கள் பயன்படுத்த வேண்டும். உங்கள் பிரித்தெடுக்கும் இயந்திரம் (extraction engine) ஒரு உரைத் தொடருக்குக் கீழே இத்தகைய ஒரு துண்டைக் கண்டறியும் போது, அந்தத் தொடரை அடிக்கோடிட்டது (underlined) என்று நீங்கள் குறிக்கலாம். இதை ஒரு தனிப்பிரிப்பு கண்டறியும் அடுக்காகக் கருதுவது உங்கள் தரவு மாதிரியை (data model) துல்லியமாக வைத்திருக்கும்: தடிமனான (bold) மற்றும் சாய்ந்த (italic) எழுத்துக்கள் எழுத்துருவின் உள்ளார்ந்த பண்புகள், ஆனால் அடிக்கோடிட்டது என்பது ஆவணத்தால் வழங்கப்பட்ட ஒரு வெளிப்புற அலங்காரம் ஆகும்.

ஒரு செயல்பாட்டுப் பாதை (A Working Pipeline)

ஒரு தெளிவான பிரித்தெடுக்கும் அமைப்புப் பணிகளைத் தனித்தனி அடுக்குகளாகப் பிரிக்கிறது. முதலில், ஒரு வடிவியல் பணியாளர் (geometry worker) பக்கத்தை ஆய்வு செய்கிறார். அது உங்கள் fontStyleMap-ஐ உருவாக்க page.commonObjs-ஐக் கேட்கிறது, செயற்கையான சாய்வு எழுத்துக்களைக் கண்டறிய ஒவ்வொரு உரை உருப்படியின் (text item) transform array-ஐ ஆய்வு செய்கிறது, மேலும் அடிக்கோடிட்ட பகுதிகளைக் கண்டறிய அருகிலுள்ள வெக்டர் பாதைகளை (vector paths) ஸ்கேன் செய்கிறது. அதன் வெளியீடு textMeta எனப்படும் ஒரு தெளிவான இடைநிலை அமைப்பாகும், அங்கு ஒவ்வொரு உரைத் தொடரும் bold, italic, மற்றும் underline ஆகிய மூன்று எளிய பூலியன் (boolean) மதிப்புகளைக் கொண்டிருக்கும்.

அடுத்து, ஒரு உரை மறுசீரமைப்பாளர் (text rebuilder) அந்த அமைப்பைப் பயன்படுத்தி குறியிடப்பட்ட (marked-up) வெளியீட்டை வழங்குகிறது. இங்கு அடுக்குகளின் வரிசை (nesting order) முக்கியமானது. சரியான படிநிலை அடிக்கோடிட்டதை (underline) வெளிப்புறமாகவும், அடுத்து சாய்ந்த எழுத்தையும் (italic), பின்னர் தடிமனான எழுத்தையும் (bold) உட்புறமாகவும் வைக்கிறது. அதாவது, முழுமையாக வடிவமைக்கப்பட்ட ஒரு உரைத் தொடர் <u><i><b>text</b></i></u> என்று மாறும். இந்த வரிசைமுறை தவறான HTML ஒன்றன் மேல் ஒன்று வருவதைத் தடுக்கிறது மற்றும் உலாவிகள் (browsers) மற்றும் ஆவண மாற்றிகளிடையே (document converters) சீரான வெளியீட்டை உறுதி செய்கிறது. இது அச்சுக்கலை தர்க்கத்தையும் (typographic logic) பிரதிபலிக்கிறது: அலங்காரம் என்பது பொருளியல் முக்கியத்துவத்தையும் (semantic emphasis), பொருளியல் முக்கியத்துவம் என்பது கட்டமைப்பல் எடையையும் (structural weight) உள்ளடக்கியது.

இந்த அணுகுமுறையின் பலம் என்னவென்றால், PDF ஏற்கனவே தன்னைப் பற்றி அறிந்திருக்கும் தகவல்களை மட்டுமே இது பயன்படுத்துகிறது. இதில் OCR இல்லை, கிளவுட் விஷன் சேவை (cloud vision service) இல்லை, மேலும் ராஸ்டரைஸ் செய்யப்பட்ட பிக்சல்களில் (rasterized pixels) இருந்து பாணிகளைக் கணிக்க இயந்திர கற்றல் (machine learning) மாதிரியும் இல்லை. நீங்கள் கோப்பின் சொந்த பொருளியல் அடுக்கை (semantic layer) வாசிக்கிறீர்கள், இது உருவாக்கிய செயலியால் ஏற்கனவே கணக்கிடப்பட்ட வடிவியல் மற்றும் மெட்டாடேட்டா (metadata) மூலம் வெளிப்படுத்தப்படுகிறது. இதன் முடிவு வேகமானது, நிலையானது மற்றும் பல்வேறு PDF உருவாக்குநர்களின் சிக்கலான சூழலிலும் துல்லியமானது.

உண்மையான பாடம் (The Real Takeaway)

எழுத்துருப் பெயர்களுக்கு எதிராக Regex பயன்படுத்துவது ஒரு பொறி. நீங்கள் சோதனை செய்த ஒரு கோப்பில் இது வேலை செய்வதால் இது ஒரு குறுக்குவழி போலத் தோன்றலாம், ஆனால் இரண்டாவது ஏற்றுமதியின் (export) சிறிய அழுத்தத்திலும் இது தோல்வியடையும். உண்மையான தகவல் ஏற்கனவே PDF-க்குள், விளக்கிகள் (descriptors), அணிகள் (matrices) மற்றும் வெக்டர் பாதைகளில் (vector paths) உள்ளது. அந்த உண்மைகளை அடிப்படையாகக் கொண்டு உங்கள் செயல்பாட்டுப் பாதையை உருவாக்குங்கள். எழுத்துரு பொருள் (font object) தடிமனானதா என்று கேளுங்கள். சாய்வுக்காக (shear) transform matrix-ஐச் சரிபார்க்கவும். அடிக்கோடிட்ட பகுதிகளைக் கண்டறிய வரையப்பட்ட துண்டுகளைப் பார்க்கவும். ஆவணத்தின் மேற்பரப்பு லேபிள்களைத் திரட்டுவதற்குப் பதிலாக, அதன் சொந்தப் பொறியியல் கட்டமைப்பைக் கேட்டால், ஒரு PDF உருவாக்குநரிலிருந்து அடுத்ததற்குத் தொடர்ச்சியாகத் தாக்குப் பிடிக்கும் பாணிகளைப் பெறலாம்.