- जो यूज़र web लेखों को सीधे terminal में पढ़ना चाहते हैं, उनके लिए James' Coffee Blog ब्लॉग पोस्ट को Linux मैनुअल पेज format में भी उपलब्ध कराता है
- वही URL होने पर भी, अगर client
Accept: text/roff भेजता है, तो HTML के बजाय roff document मिले—इसके लिए HTTP content negotiation का उपयोग किया गया है
- हर पोस्ट की
.man file TITLE, AUTHOR, PUBLISHED, POST, URL sections वाले template से generate की जाती है
- body में Markdown source डाला गया है ताकि HTML की तुलना में पढ़ना आसान हो, लेकिन मैनुअल पेज में spacing हमेशा साफ-सुथरी fit नहीं होती
- NGINX
text/roff request को detect करके URL को .man file में rewrite करता है, इसलिए इसे curl से save करने के बाद man./post.page की तरह खोला जा सकता है
ब्लॉग पोस्ट को man से पढ़ना
- Linux के मैनुअल पेज terminal में command usage देखने का basic तरीका हैं, और आम तौर पर इन्हें
man <command> से खोला जा सकता है
- उदाहरण के लिए,
tac command का manual इस तरह देखा जाता है
man tac
- James' Coffee Blog ने web ब्लॉग पोस्ट को भी उसी तरह पढ़ने के लिए, पोस्ट URL से
roff version download करके man से खोलने वाला flow बनाया है
- वास्तविक request का उदाहरण यह है
curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page && man ./post.page
HTTP content negotiation से format चुनना
- implementation का केंद्र HTTP content negotiation है, जिससे client server को बताता है कि उसे किस response format की जरूरत है
Accept header मनचाहा content type बताने के लिए इस्तेमाल होता है
- उदाहरण के लिए,
Accept: image/png का मतलब है कि संभव हो तो PNG file भेजें
- कई content types और priorities भी specify की जा सकती हैं, लेकिन यहाँ केवल किसी specific format की request का उपयोग किया गया है
- ब्लॉग पोस्ट को मैनुअल पेज format में लेना हो तो
Accept: text/roff header भेजा जाता है
- server इस header को देखकर HTML के बजाय
man में खोला जा सकने वाला text/roff response लौटाता है
.man file generate करने का तरीका
- Linux मैनुअल पेज roff syntax में लिखे जाते हैं
- site को हर ब्लॉग पोस्ट के लिए
man page version generate करने के लिए modify किया गया
- इस्तेमाल किए गए template की structure यह है
.TH jamesg.blog 1 "" "jamesg.blog"
.SH TITLE
...
.SH AUTHOR
James' Coffee Blog (https://jamesg.blog)
.SH PUBLISHED
...
.SH POST
...
.SH URL
...
- template domain name को header में रखता है और पाँच sections बनाता है
- TITLE
- AUTHOR
- PUBLISHED
- POST
- URL
- body में Markdown source का उपयोग किया गया है
- मैनुअल पेज में spacing हमेशा ठीक से align नहीं होती
- फिर भी यह HTML से पढ़ने में आसान था, और plain text की तुलना में headings और paragraphs के separation में information loss कम था
curl से लेना और man से खोलना
- ब्लॉग पोस्ट का
roff version इस command से request किया जा सकता है
curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/ > post.page
- save किया गया result local मैनुअल पेज की तरह खोला जा सकता है
man ./post.page
- अगर सामान्य browser उसी पोस्ट URL को request करता है, तो उसे HTML version मिलता है
- इसके विपरीत ऊपर वाली
curl command उसी URL के लिए explicitly text/roff version request करती है
NGINX में .man file पर rewrite करना
- server NGINX configuration की कुछ lines से
text/roff requests को अलग से handle करता है
/etc/nginx/nginx.conf में ऐसे variables declare किए जाते हैं जो specific content type detect होने पर flag set करते हैं
map $uri $redirect_suffix {
~^/(.*)/$ $1;
default "";
}
map $http_accept $redirect_location {
default "";
"~^text/roff" 1;
}
- site configuration file
/etc/nginx/sites-enabled के नीचे roff page requests handle करने वाला rule add किया जाता है
server {
...
location / {
if ($redirect_location = 1) {
rewrite ^/(.*)/$ /$1.man last;
}
...
}
}
- यह setting
Accept: text/roff header होने पर URL के अंत का slash हटाकर .man जोड़ती है
- परिणामस्वरूप NGINX हर पोस्ट के
index.html के बजाय corresponding .man file पढ़ता है
- इससे वही ब्लॉग पोस्ट web browser में HTML के रूप में और terminal में Linux मैनुअल पेज के रूप में पढ़ी जा सकती है
1 टिप्पणियां
Hacker News की राय
ब्लॉग subscription के तरीके के रूप में deb repository देना अच्छा लगेगा
apt updateसे सभी पोस्ट मिल जाएँ, औरman your-blogसे ताज़ा पोस्ट व सभी पोस्ट के index links देखे जा सकें, कुछ ऐसाsubscribe करने में डर लगेगा
इन्हें dwww package से local रूप से देखा जा सकता है: “Read all on-line documentation with a WWW browser”
https://packages.debian.org/bookworm/dwww
Joerg Jaspert पहले Linux Gazette package maintainer थे: https://people.debian.org/~joerg/ (2002)
operating system में information delivery और documentation को integrate करने के अब तक देखे गए उदाहरणों में यह सबसे अच्छे उदाहरणों में से एक था, और खासकर पारंपरिक terminal-based interfaces की तुलना में man/info docs को ज़्यादा उपयोगी बनाता था
Debian से जुड़ा blog Debian Planet भी है, लेकिन लगता है वह Debian के अपने package के रूप में कभी उपलब्ध नहीं कराया गया
सच कहें तो blog subscription के लिए RSS शायद बेहतर विकल्प है
https://github.com/capjamesg/jamesg.blog.deb में नीचे दिए commands से सिर्फ़ man page वाला deb file बनाने की चीज़ें हैं
git clone [https://github.com/capjamesg/jamesg.blog.deb](<https://github.com/capjamesg/jamesg.blog.deb>)cd jamesg.blog.debdpkg-deb --build --root-owner-group jamesg.blogsudo dpkg -i jamesg.blog.debफिर आपको
Processing triggers for man-db (2.9.1-1) ...जैसा output दिखेगा, जिसका मतलब है किman jamesg.blogके लिए manual page उपलब्ध हैअभी सिर्फ़ placeholder है, शायद कल तक पूरा कर दूँगा
जल्द ही यह blog post भी बन सकता है
fork करने या intermediate file लिखने की ज़रूरत नहीं, सीधे
manमें pipe कर सकते हैंcurl -sL -H "Accept: text/roff" [https://jamesg.blog/2024/02/28/programming-projects/](<https://jamesg.blog/2024/02/28/programming-projects/>) | man -l -{curl,wget}को command में pipe करने वाली बहस शुरू हो जाएगीदोस्त, दोस्तों को stream सीधे command में pipe नहीं करने देते
https://news.ycombinator.com/item?id=39554044
संदर्भ के लिए,
curl -sL -H "Accept: text/roff" [https://jamesg.blog/2024/02/28/programming-projects/](<https://jamesg.blog/2024/02/28/programming-projects/>) | man -l /dev/stdinमेरे environment में काम करता हैroff file को local में save करने की ज़रूरत नहीं
bashजैसी जगह pipe करना आम तौर पर bad practice माना जाता हैनिजी तौर पर मुझे यह ठीक लगता है। सुरक्षा के लिहाज़ से इसका मतलब समझने वाले लोग यह conversion तरीका भी लगभग निश्चित रूप से जानते होंगे, इसलिए खास तौर पर बताने की ज़रूरत नहीं
लेकिन beginners को बताने के लिए यह अच्छा नहीं है। किसी दिन वे फँस सकते हैं। skill बढ़ेगी तो वे स्वाभाविक रूप से ऐसी functionality जान लेंगे, और तब तक उम्मीद है कि implications भी सीख चुके होंगे
यह मेरा लिखा हुआ नहीं है: https://www.seancassidy.me/dont-pipe-to-your-shell.html
/usr/bin/man: illegal option -- lMac पर pipe इस्तेमाल करने वाला one-line command बनाने की कोशिश की, लेकिन लगातार error आया
macOS के
manimplementation में-lflag नहीं है। manual page देख लियाman -l <(curl -sL -H "Accept: text/roff" https://jamesg.blog/2024/02/28/programming-projects/)अगर बात ऐसे URL की हो जो terminal में मज़ेदार चीज़ें करते हैं, तो मुझे textfiles.com पर पहले देखा हुआ एक उदाहरण याद है
यह VT100 terminal codes से एक छोटी animated movie दिखाने जैसा है, और सब कुछ एक ही URI से serve होता है
आधुनिक systems पर इसे speed limit लगाकर देखा जा सकता है
curl --limit-rate 1000 [http://textfiles.com/sf/STARTREK/trek.vt](<http://textfiles.com/sf/STARTREK/trek.vt>) && resetresetइसलिए डाला है क्योंकि terminal गड़बड़ा सकता हैदूसरे terminal-based URI में
curl cheat.sh/tar/के बाद दिए गए program के usage examples लाता है, औरcurl wttr.in/berlinterminal formatting के साथ weather information लाता हैअसल में यह काफी simple है, सबसे मुश्किल हिस्सा frames generate करना है
यह
ffmpeg+img2txt.pyसे किया जा सकता है: https://github.com/bfontaine/RickASCIIRoll/tree/master/movie...https://16colo.rs/ का एक पुराना mirror है, इसलिए अब तक public हुई ज़्यादातर ANSI art देखी जा सकती है
उदाहरण:
curl ansi.hrtk.in/ungenannt_1453.anshttps://itsfoss.com/star-wars-linux/
trittyइस्तेमाल करने पर 1200/9600 BPS transfer speed की नकल की जा सकती हैअब ज़रूरत सिर्फ़ ऐसे converter की है जो Markdown को roff में बदल दे, और ढूँढने पर पता चला कि यह पहले से मौजूद है
https://github.com/postmodern/kramdown-man
https://rtomayko.github.io/ronn/ronn.1.html
https://kristaps.bsd.lv/lowdown/
[0]: https://pandoc.org/
md2groffsuckless/2f30/cat-v जैसी communities में काफ़ी समय से मौजूद हैhttps://codeberg.org/nereusx/md2roff
Emacs packages में एक ऐसा है जो Abelson और Sussman की SICP को Info directory में install कर देता है
बस
M-x package-install sicp RETटाइप करना होता हैइसे देखकर लगा कि modified feed reader से blog archive की पूरी bookshelf भी install की जा सकती है
Emacs में Info पढ़ने पर bookmarks भी इस्तेमाल किए जा सकते हैं
chicken-schemeभी install कर लें। फिर इसे root के रूप में चलाएँchicken-install srfi-203chicken-install srtfi216SICP के लिए
~/.csircइस तरह है(import scheme)(import (srfi 203))(import (srfi 216))(define (inc x) (+ x 1))(define (dec x) (- x 1))उसके बाद हमेशा की तरह user geiser और chicken के लिए geiser इस्तेमाल करें
इंटरनेट पर खोजने से शायद जवाब मिल जाए, लेकिन HN पर पूछना चाहता हूँ
हाई स्कूल के समय HP-UX पर मुझे याद है कि किसी ने underlined word, यानी section reference, पर jump करने के लिए कोई key combination दबाकर दिखाया था, लेकिन बिल्कुल याद नहीं कि कौन-सी key थी
man(1)औरman(7)भी देखा, पर नहीं मिला। हो सकता है यह झूठी याद होman ohmanमूल रूप सेnroff -man /usr/share/man/man1/ohman.1 | $PAGERहैयानी आप man या nroff से interact नहीं कर रहे, बल्कि pager से interact कर रहे हैं
आजकल
lessसबसे common है, औरmoreभी असल में less ही होने की काफ़ी संभावना है, लेकिन पहले दूसरे भी थे और HPUX शायदpgजैसा कुछ इस्तेमाल करता रहा होpgAT&T लाइन का था,moreBSD लाइन का, औरlessGNU लाइन कातीनों
/से regular expression search शुरू करते हैं, इसलिए underline हो या न हो, खोजा जा सकता हैlesstag files भी support करता है, इसलिएtसे अगले tag पर jump किया जा सकता हैdthelpviewके बारे में सोच रहे हों। यह man pages दिखाता रहा हो सकता हैinfocommand से खुलने वाले texinfo जैसा लगता हैविडंबना यह है कि मूल groff documents का बड़ा हिस्सा texinfo में लिखा गया है: https://lists.gnu.org/archive/html/groff/2005-10/msg00107.ht...
पता नहीं इस छोटी-सी बात ने मेरी कमी निकालने वाली प्रवृत्ति को क्यों छेड़ दिया। शायद इसलिए कि इंटरनेट पर कोई थोड़ा-सा गलत था
हो सकता है कि यह शुरुआत से ही बेवजह Linux-केंद्रित था, या मुझे कुछ और उम्मीद थी लेकिन आखिर में यह NGINX के content negotiation का छोटा-सा demo निकला
खैर, कुछ बेकार-सी बातें हैं जो मैं फिर भी कहना चाहता हूं
सख्ती से कहें तो यह roff return नहीं कर रहा।
.THजैसी चीजें roff अपने-आप में नहीं हैं, बल्कि man page लिखने के लिए macro package का हिस्सा हैंMarkdown-to-roff conversion न देखकर निराशा हुई। मुझे लगा था कि यही इस लेख का दिलचस्प हिस्सा होगा, और कम-से-कम कोई मौजूदा tool तो इस्तेमाल किया जा सकता था
इसी तरह, इस वजह से text formatting भी सच में सही नहीं बैठती। roff input में वाक्य के अंत वाले
.और दूसरे इस्तेमाल वाले.में फर्क करने के लिए जानबूझकर एक वाक्य को एक line में रखा जाता हैसाथ ही
.से शुरू होने वाली हर line command मानी जाएगी, जिससे समस्या हो सकती हैया फिर शायद मैं बस एक चिड़चिड़ा बूढ़ा हूं
groff,nroffजैसे दूसरे tools भी हैं, इसलिए और उलझन हुई“roff/man page/nroff/दूसरे variants क्या हैं और उन्हें कैसे इस्तेमाल करते हैं” समझाने भर वाला लेख भी अपने-आप में एक पूरा blog post बन सकता है
अगर कोई छोटा और साफ explanation होता तो मेरे लिए भी अच्छा होता, और लगता है दूसरों के लिए भी मददगार होगा
Markdown-to-roff को मैंने v2 के लिए सोचा था। जब मैं parser implement करने के बारे में सोचने लगा, तो किसी ने https://github.com/sunaku/md2man बताया, और लगता है इससे यह समस्या हल हो जाती है
GitHub Pages पर चलने वाली अपनी Python site में इसे कैसे integrate करूं, यह देखना होगा, इसलिए थोड़ा काम करना पड़ेगा
Pandoc Markdown को man-page roff में बहुत आसानी से बदल सकता है
उसे दिए गए template में डाल दें तो यह असली man page जैसा और बेहतर दिखेगा
RFC 4263 के हिसाब से सही media type text/troff है: https://www.rfc-editor.org/rfc/rfc4263.html
शानदार idea है। अब बस “मेरे blog posts को playable DOOM WAD के रूप में उपलब्ध कराना” आने तक timer लगाना है