Skip to main content

[Python] docutils package (hay nhật ký tìm hiểu 1 python package)

Bài viết này dành cho những ai biết các khái niệm pip, virtualenv, package/module trong python. Hoặc những ai muốn xem ví dụ sử dụng một số câu lệnh để khám phá 1 directory.

Docutils is a modular system for processing documentation into useful formats, such as HTML, XML, and LaTeX. For input Docutils supports reStructuredText, an easy-to-read, what-you-see-is-what-you-get plaintext markup syntax.

Tóm lại module (hay package) này thực hiện các công việc giúp đọc 1 file .rst (reStructuredText) và cho phép xuất ra các output khác nhau (HTML, XML, LaTeX)

Ví dụ:
 rst2html.py monitor.rst out.html
Document của docutils khá là sơ sài, có mỗi page này có vẻ có chút thông tin:
http://docutils.sourceforge.net/docs/dev/hacking.html


Các bước hoạt động

docutils chuyển đổi 1 file .rst sang .html qua 4 giai đoạn:
1. Reader : đọc document từ source file và chuyển cho Parser
2. Parser: phân tích document nhận được, tạo 1node tree document.
3. Transform: thực hiện tranform ví dụ như biến 1 reference thành 1 link cụ thể.
4. Writer: nhận node tree sau khi transform và thực hiện ghi ra file đích.

Introspect docutils (soi và ngắm)


Để cho sạch sẽ, cài docutils vào 1 virtualenv riêng.

hvn@archhvn: /tmp () $ virtualenv2 crazy
New python executable in crazy/bin/python2
Also creating executable in crazy/bin/python
Installing Setuptools.................................................................................................................................
.............................................................................................done.
Installing Pip........................................................................................................................................
......................................................................................................................................................
.......................................done.
hvn@archhvn: /tmp () $ . crazy/bin/activate
(crazy)hvn@archhvn: /tmp () $ pip install docutils
Downloading/unpacking docutils
  Downloading docutils-0.11.tar.gz (1.6MB): 1.6MB downloaded
...
Successfully installed docutils
Cleaning up...

Tổng số file python code:

(crazy)hvn@archhvn: /tmp/crazy/lib/python2.7/site-packages/docutils () $ find . -type f  -name '*.py' | wc -l
108
Có vẻ nhiều, nhưng bỏ đi các file languages/ thì chỉ còn:
 $ find . -type f  -name '*.py' | grep -v languages | wc -l
60
Các thư mục:
$ find . -type d
.
./languages
./parsers
./parsers/rst
./parsers/rst/directives
./parsers/rst/languages
./parsers/rst/include
./readers
./transforms
./utils
./utils/math
./writers
./writers/html4css1
./writers/pep_html
./writers/s5_html
./writers/s5_html/themes
./writers/s5_html/themes/medium-white
./writers/s5_html/themes/small-black
./writers/s5_html/themes/medium-black
./writers/s5_html/themes/default
./writers/s5_html/themes/small-white
./writers/s5_html/themes/big-black
./writers/s5_html/themes/big-white
./writers/latex2e
./writers/xetex
./writers/odf_odt

Như phần phân tích cách hoạt động, ta thấy code được bố trí thành các sub-packages, mỗi sub-package chứa 1 thành phần. Mỗi file __init__.py trong các subpackage implement các class base cho các file bên trong subpackage đó.

Việc quan sát các thành phần như vừa làm ở trên có thể sử dụng lệnh `tree` (không có thì cài), hay ls -R.

Đếm dòng 10 file có nhiều line nhất

$ find . -name '*.py' -exec wc -l {} \; | sort -nr | head
5249 ./utils/math/math2html.py
3291 ./writers/odf_odt/__init__.py
3080 ./writers/latex2e/__init__.py
3072 ./parsers/rst/states.py
2204 ./nodes.py
1734 ./writers/html4css1/__init__.py
1538 ./statemachine.py
1157 ./writers/manpage.py
905 ./transforms/references.py
904 ./utils/smartquotes.py
Xem ở top-level:
$ find . -maxdepth 1 ! -name '*.pyc'  #(bỏ hết các file *.pyc)
.
./io.py
./core.py # quan trọng nhất , chứa các helper method để dùng docutils
./_compat.py
./statemachine.py # khá là trừu tượng, docutils hoạt động như 1 statemachine
./examples.py # chứa 3 ví dụ đơn giản hướng dẫn dùng docutils ở code level
./__init__.py # chứa các base class chung nhất
./frontend.py # parse config, ...
./nodes.py  # chứa các class về node và tree, bởi docutils đọc ReST vào và tạo thành 1 node tree. Implement visitor theo pattern Visitor của GoF95
./languages # support multiply langs
./parsers # chứa các parser (chỉ có rst )
./readers # chứa các reader
./transforms # chứa các transform
./utils # chứa các function hỗ trợ
./writers # chứa các writer như HTML, XML, ODT ...

Docutils được viết theo OO, dễ dàng tìm được hàng đống class:

 $ grep '^class' *.py
core.py:class Publisher:
frontend.py:class Values(optparse.Values):
frontend.py:class Option(optparse.Option):
frontend.py:class OptionParser(optparse.OptionParser, docutils.SettingsSpec):
frontend.py:class ConfigParser(CP.RawConfigParser):
frontend.py:class ConfigDeprecationWarning(DeprecationWarning):
__init__.py:class ApplicationError(StandardError):
__init__.py:class DataError(ApplicationError): pass
__init__.py:class SettingsSpec:
__init__.py:class TransformSpec:
__init__.py:class Component(SettingsSpec, TransformSpec):
io.py:class InputError(IOError): pass
io.py:class OutputError(IOError): pass
io.py:class Input(TransformSpec):
io.py:class Output(TransformSpec):
...

Ngoài phần example ra, khó có thể biết cách dùng docutils thế nào, may mắn là có sẵn các script CLI mà docutils cung cấp, ta sẽ dùng 1 chương trình debuger để chọc vào xem docutils hoạt động thế nào.

Khám phá
$ ls /tmp/crazy/bin/rst2*
/tmp/crazy/bin/rst2html.py   /tmp/crazy/bin/rst2odt_prepstyles.py  /tmp/crazy/bin/rst2s5.py
/tmp/crazy/bin/rst2latex.py  /tmp/crazy/bin/rst2odt.py             /tmp/crazy/bin/rst2xetex.py
/tmp/crazy/bin/rst2man.py    /tmp/crazy/bin/rst2pseudoxml.py       /tmp/crazy/bin/rst2xml.py


Ta có thể thử với /tmp/crazy/bin/rst2html.py.
Cài ipdb (ipython + pdb) để debug, debugger is your friend!

apt-get install -y python-dev
pip install -y ipdb
Giờ chỉ cần thêm 2 dòng vào trước đoạn code bạn muốn tìm hiểu, chạy script để nó nhảy ra ipdb rồi dùng debugger này để khám phá docutils.

import ipdb
ipdb.set_trace()
Tổng kết
- docutils được sử dụng bởi sphinx, và nhiều project liên quan đến document khác, nên chất lượng code thuộc loại rất tốt.
- docutils có cách parse script argv khá hay, nó không để ở level cao nhất của script mà ẩn ẩn phía dưói.

Ví dụ, đây là nội dung toàn bộ file script rst2html.py

 $ cat /tmp/crazy/bin/rst2html.py
#!/tmp/crazy/bin/python2

# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing HTML.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates (X)HTML documents from standalone reStructuredText '
               'sources.  ' + default_description)

publish_cmdline(writer_name='html', description=description)

- core.py chứa các publisher, là phần hồn của docutils, nó sử dụng các thành phần reader, parser, transform và writer để tạo thành 1 quy trình hoàn chỉnh.
- trong code có nhiều đoạn dùng "or" để gán default value khá hay:
x = xyz or "5"
Hết.

Comments

  1. các câu lệnh trong bài này đã được chuyển thể thành script :

    https://github.com/familug/FAMILUG/blob/master/Bash/pyexplorer.bash

    ReplyDelete

Post a Comment

Popular posts from this blog

Tài liệu và hướng dẫn học Python

Để tiết kiệm thời gian, tốt nhất là đi học PyMI Updated: 130617 Sau đây là các tài liệu khuyên dùng: Vì nhiều lý do, nên học python2.7 tại thời điểm hiện tại (giờ là tháng 6/2013 - muốn biết tại sao thì tự tìm hiểu) python 3.5+ (giờ là tháng 2/2017) Chuẩn bị: 1. biết bật tắt máy 2. biết cài python 3. tập gõ 10 ngón - gõ 2 ngón hay 1 ngón cũng không sao, nhưng 10 ngón là cách dễ nhất để gõ nhanh nhất. Tài liệu - Nên dùng tài liệu tại trang chủ của Python làm chính, tham khảo thêm các tài liệu khác tại http://www.familug.org/2016/12/free-ebook.html Căn bản, mới học 1.1 Python PyMI.vn https://pymi.vn/tutorial/ 1.2. Python offical tutorial kết hợp làm bài tập trên HackerRank  (đề bài bằng tiếng Anh, nhưng Google translate 1 lúc cũng ra vì có nhiều ví dụ mẫu đi kèm). Học viên của Pymi.vn có rất nhiều học viên đã tự học với Learn Python the hard way nhưng chưa thấy ai thành công cả. Hai link dưới nên đọc sau khi đã nắm được những phần cơ bản của ngôn ngữ pytho...

The PyMiers

New FAMILUG